上一篇说道了用强制转换绕过限制,还有些不甘心,这使用起来也太麻烦了,还有一大堆强转。
刚刚看了一下宏的用法,发现可以用宏定义来简化操作。
#define _OBJECT(classname) \
public: \
typedef void (classname##::*pFun##classname)(string); \
virtual bool Register(A* obj, pFun##classname function); \
public: \
pFun##classname m_pfun##classname;
#define _IMPLEMENT(classname) \
bool classname##::Register(A*obj, pFun##classname function) \
{ \
int* ptemp_fun= (int*)&function; \
obj->m_pfunA= *(A::pFunA*)ptemp_fun; \
return true; \
}
class A
{
_OBJECT(A)
public:
};
_IMPLEMENT(A)
class B: public A
{
_OBJECT(B)
public:
B(string b, int ib)
{
m_b= b;
m_ib= ib;
}
void testFunB(string str)
{
cout<<m_b<<":"<<m_ib<<";"<<"B类函数:"<<str<<endl;
return;
}
private:
string m_b;
int m_ib;
};
_IMPLEMENT(B)
class C:public A
{
_OBJECT(C)
public:
C(string c)
{
m_c= c;
}
void testFunC(string str)
{
cout<<m_c<<";"<<"C类函数:"<<str<<endl;
return;
}
private:
string m_c;
};
_IMPLEMENT(C)
但是_IMPLEMENT这个宏定义破坏了封装性原则,不过使用起来倒还方便
C *c= new C("我是C");
B *b= new B("我是B", 1);
b->Register(c, &B::testFunB);
(c->*(c->m_pfunA))("c调用a的函数指针");
这个函数指针有个很不好的问题,就是不能使用成员变量,由于函数在code区,而成员在栈中,这就使得我们使用函数指针仅仅是使用code区的东西,而在找成员的时候找不到(这很正常,C中没有B的成员),就会使程序崩溃,所以说还是相当不安全的。