|
|
-----------------------------------------------------------
引言 1
以前发过什么“回调动态成员”的帖子中提到,
一个多继承的类 的成员函数指针,无法类型转换。
最后我用了union_cast解决。
其实当时还不知道多继承和虚拟继承的指针漂移的问题。
这几个月来,我的RTTI规范几次修改,最近终于固定了下来。
-----------------------------------------------------------
引言 2
今天正好回过头来重新编写Event类。
(改为,不立即call back,而是存入队列,稍候再一次性调用他们,
防止event handler破坏 UI 类库的消息处理机制)
于是不得不zhong视,安全的 "thiscall"
===========================================================
本帖要探讨什么问题?
不探讨CEvent问题,这点我没有疑惑,
CEvent也不需要支持虚函数回调(就是说不支持函数指针的指针)
不探讨RTTI,这我玩的很熟了,再说与本帖也没多少关系。
探讨一下virtual函数调用时的this指针转型。
探讨一下安全的thiscall,以及是否使用RTTI来进行thiscall
===========================================================
先不急着看virtual函数的case,先看下下面的代码。当然也可以skip~
(对下面的代码,我没有疑问,我的疑问在后面~~)
class B2
{
int b;
public:
void fb(){ b=0; cout<<b<<" this="<<this<<" B1::fb\n"; }
};
class B1{};
class Cls: public B1, virtual public B2
{
int m;
public:
void func(int a,int b){ m=a; cout<<m<<" "<<b<<" "<<" this="<<this<<" Cls::func\n"; }
};
void main()
{
Cls *p=new Cls;
// (((__obj *)p)->*union_cast<void (__obj::*)(void)>(B2::fb)) ( );
//----上面的调用,因为this不正确,所以类开头的信息,vbase表被搞坏了------------
(((__obj *)p)->*union_cast<void (__obj::*)(int,int)>(Cls::func)) (1, (1, 2) );
// 当指针漂移存在的时候,C++禁止成员函数的类型转换。包括重新解释转换
p->func(3,4);
p->fb();
//************************************************************
这个调用:(((__obj *)p)->*union_cast<void (__obj::*)(void)>(B2::fb)) ( );
是错误的,因为编译器无法 静态地 转换 this 指针,这很简单。道理我就不说了。
-------------------------------------------------------------------
非virtual成员函数调用时,this是静态转型的,从源代码中就可以直接看出来,
应该如何转换this。 当然,除非你违规操作。
下面进入正题...
|
|