msi*_*yer 6 c++ function-pointers
我正在阅读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; };
};
Run Code Online (Sandbox Code Playgroud)
该片段后跟以下段落:
假设我们为类C创建一个成员函数指针.在这个例子中,Afunc和Cfunc都是C的成员函数,所以允许我们的成员函数指针指向Afunc或Cfunc.但是Afunc需要一个指向C :: A(我称之为Athis)的指针,而Cfunc需要一个指向C的指针(我称之为Cthis).编译器编写者通过一个技巧处理这种情况:他们确保A物理存储在C的开头.这意味着Athis == Cthis.我们只有一个值得担心,而且全世界都很好.
我想要理解的唯一一件事就是上段中的BOLD和ITALICS中的一行.
我不完全理解Afunc需要一个指向C :: A 的指针,而Cfunc需要一个指向C的指针是很自然的.
任何帮助,将不胜感激.
通过在C++中调用成员函数,内部发生的是实例作为隐藏的第一个参数传递(请注意,这种行为严格地是实现定义的行为.C++标准对此主题没有任何说法,它只是一个非常常见的实现方式):
x.f(y); // is treated internally as:
f(&x, y);
Run Code Online (Sandbox Code Playgroud)
然后可以通过this指针获得第一个参数.
现在,Afunc在上面的示例中,内部具有签名,void Afunc(A* const this)同时CFunc具有内部签名void CFunc(C* const this).
请注意,两种情况下的参数类型都不同,因此当您在同一对象上调用函数时,必须传递不同的指针.C++通过定义从任何派生对象到其基础对象的隐式转换来解决这个问题.也就是说,在以下代码中:
C* pc = something;
pc->Afunc();
Run Code Online (Sandbox Code Playgroud)
此代码在内部处理类似于以下(伪代码):
C* pc = something;
Afunc(static_cast<A*>(pc));
Run Code Online (Sandbox Code Playgroud)
对于单继承,这个强制转换是通过引用中提到的技巧进行的无操作(即它可以被删除):C对象及其父A对象存储在同一物理地址中.类型的对象C被存储在地址x中的存储器中该类型的其父对象这样的方式在物理上布置A在也存储在该地址x,并且之后是所有其他成员C可以具有(但在你的情况下,它具有没有成员,和sizeof(C) == sizeof(A)).