class A { public: virtual int Afunc() { return 2; }; }; class B { public: int Bfunc() { return 3; }; }; // C is a single inheritance class,derives only from A class C: public A { public: int Cfunc() { return 4; }; }; // D uses multiple inheritance class D: public A,public B { public: int Dfunc() { return 5; }; };
该片段后跟以下段落:
Suppose we create a member function pointer for class C. In this
example,Afunc and Cfunc are both member functions of C,so our member
function pointer is allowed to point to Afunc or Cfunc. But Afunc
needs a this pointer that points to C::A (which I’ll call Athis),
while Cfunc needs a this pointer that points to C (which I’ll call
Cthis). Compiler writers deal with this situation by a trick: they
ensure that A is physically stored at the start of C. This means that
Athis == Cthis. We only have one this to worry about,and all’s well
with the world.
我想要理解的唯一一件事就是上段中的BOLD和ITALICS中的一行.
我不完全理解Afunc需要一个指向C :: A的指针,而Cfunc需要一个指向C的指针是很自然的.
任何帮助,将不胜感激.
解决方法
x.f(y); // is treated internally as: f(&x,y);
然后可以通过this指针获得第一个参数.
现在,上面示例中的Afunc内部具有签名void Afunc(A * const this),而CFunc具有内部签名void CFunc(C * const this).
请注意,两种情况下的参数类型都不同,因此当您在同一对象上调用函数时,必须传递不同的指针. C通过定义从任何派生对象到其基础对象的隐式转换来解决此问题.也就是说,在以下代码中:
C* pc = something; pc->Afunc();
C* pc = something; Afunc(static_cast<A*>(pc));
对于单继承,这种强制转换是通过引用中提到的技巧进行的无操作(即它可以被删除):C对象及其父对象存储在同一物理地址中.存储在存储器中的地址x的类型C的对象物理地布置,使得其类型A的父对象也存储在地址x处,并且其后是C可能具有的所有其他成员(但是在你的情况下,它没有成员,sizeof(C)== sizeof(A)).