函数指针

Function Pointers

本文关键字:指针 函数      更新时间:2023-10-16

我正在阅读Don Clugston关于Codeproject的一篇文章。这是一篇漂亮的文章,非常有名。在下面的代码片段中,我发现一个特定的概念很难理解:

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; };
};

该代码段后跟以下段落:

假设我们为类 C 创建一个成员函数指针。在此 例如,Afunc 和 Cfunc 都是 C 的成员函数,所以我们的成员 允许函数指针指向 Afunc 或 Cfunc。但是阿丰克 需要一个指向 C::A 的指针(我称之为 Athis), 而 Cfunc 需要一个指向 C 的 this 指针(我称之为 Cthis)。编译器编写者通过一个技巧来处理这种情况:他们 确保 A 以物理方式存储在 C 的开头。这意味着 阿西斯 == 奇斯。我们只有一个这个需要担心,一切都很好 与世界。

我唯一想了解的是上一段中粗体和斜体的行。

我不完全理解 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对象及其父对象A存储在相同的物理地址。存储在内存中x地址的 C 类型的对象以这样的方式进行物理布局,即其类型 A 的父对象存储在地址x,并且后跟C可能具有的所有其他成员(但在您的情况下,它没有成员, 和sizeof(C) == sizeof(A))。