提供函数指针访问C ++类的私有成员 - 是否可能?

时间:2015-09-17 19:29:36

标签: c++ function-pointers private-members

以下是我要完成的事情:

-Client在类(foo)

中注册一个函数(fun)

-Fun有一个通用的表单类型函数(int,int,int)

-Foo然后,在执行其工作时,调用可能需要访问私有成员的函数

重点是允许Foo在其工作过程中使用的用户定义函数。是否有C ++等模式/细微差别..这会使这个可行吗?

最糟糕的情况我可以公开数据但我很好奇是否存在更好的事情。

TIA

示例:

class foo;

typedef float (*client_fun)(foo &obj, int &i);
class foo
{
   client_fun their_fun;

   int private_info;

 public:
   foo(): private_info(42){};

   void set_fun(client_fun _fun)
     {
        their_fun = _fun;
     }

   float run_foo()
     {
        //Oversimplified example of what it would be doing.
        //their_fun would be called as part of a complicated method
        int i;
        i = 1;
        return their_fun(*this, i);
     }

};

float fancy_fun(foo &obj, int &i)
{
   //needs access to private info
   return (i/obj.private_info);
}

int main()
{
   //Hypothetical use
   foo my_foo;

   my_foo.set_fun(fancy_fun);

   //Can't access the private member
   my_foo.run_foo();

   return 0;
}

G ++ example.cpp:

example.cpp: In function ‘float fancy_fun(foo&, int&)’:
example.cpp:8:8: error: ‘int foo::private_info’ is private
    int private_info;
        ^
example.cpp:32:18: error: within this context
    return (i/obj.private_info);

1 个答案:

答案 0 :(得分:0)

这是回答我问题的模式。

#include <iostream>

class engine;

class settings
{
   //Can friend the engine class if we have private members we want to be able to call
   friend class engine;

 public:
   int private_info;
   settings()

     {
        private_info = 42;
     };
};

typedef float (*fn_ptr)(settings &);

class engine
{
   //private info will still be private to the world since the engine owns the settings object
   settings my_settings;
   fn_ptr my_fn;

 public:

   engine(): my_settings(){};

   void set_fun(fn_ptr _ptr)
     {
        my_fn = _ptr;
     }

   void run()
     {
        std::cout << my_fn(my_settings, 1) << "\n";
     }
};


float fancy_fun(settings &obj, size_t i)
{
   //needs access to private info
   return (obj.private_info);
}

int main()
{
   //Hypothetical use
   engine my_engine;

   my_engine.set_fun(fancy_fun);


   //Error! Private!
   //my_engine.my_settings;

    /*Is now accessing the public member of a private object
    * using an appropriately specified user function */
   my_engine.run();

   return 0;
}