如何在内部发生派生类和基类之间的转换,以及编译器如何知道或存储对象的大小?
例如,以下内容:
class A
{
public:
A():x(2){};
private:
int x;
};
class B : public A
{
public:
B():A(),y(5){};
private:
int y;
};
class C : public B
{
public:
C():B(),z(9){};
private:
int z;
};
int main()
{
C *CObj = new C;
B *pB = static_cast<B*>(CObj);
delete CObj;
}
Run Code Online (Sandbox Code Playgroud)
编辑:一定是这样的:
B BObj = static_cast<B>(*CObj);
Run Code Online (Sandbox Code Playgroud)
您的代码中没有任何"派生到基础"转换.你的代码中有一个指针 - 派生到指针到基础的转换.(此转换不需要任何显式转换,BTW)
B *pB = CObj; // no need for the cast
Run Code Online (Sandbox Code Playgroud)
为了执行指针转换,不需要知道对象的大小.因此,不清楚您对"对象大小"的引用来自何处.
实际上,在典型的实现中,非多态类的单继承层次结构的上述转换纯粹是概念性的.即,除了简单地将派生指针的数值复制到基指针之外,编译器不会做任何事情.无需额外信息即可执行此操作.没有尺寸,没有任何东西.
在更复杂的情况下(如多重继承),编译器可能确实必须生成调整指针值的代码.它确实需要知道所涉及对象的大小.但涉及的大小总是编译时的,即它们是编译时常量,这意味着编译器会立即知道它们.
在更复杂的情况下,如虚拟继承,这种转换通常由隐式构建在对象中的运行时结构支持,其中包括所有必要的内容.如果实现选择这样做,也可以包括对象的运行时大小.