c – 功能指针

我在Codeproject上经过Don Clugston的 article.这是一篇很棒的文章,很有名.在下面的代码片段中,我发现了一个非常难以理解的特定概念:
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的指针是很自然的.

任何帮助,将不胜感激.

解决方法

通过在C中调用成员函数,内部发生的是实例作为隐藏的第一个参数传递(请注意,这种行为严格地是实现定义的行为.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)).

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...