【发布时间】:2020-05-02 11:53:43
【问题描述】:
据我所知,我们可以使用基类指针来寻址和调用派生类中的虚函数,因为基类指针的指针范围更有限。但是我只想知道,基类指针是怎么知道派生类从哪里开始的?
例如,对于记录A、B、C都有自己的数据成员,我们可以分两种不同的类别来讨论这个问题:1.A、B、C都有自己的虚函数; 2. A、B、C只有自己的数据成员,没有任何虚函数
class A {...};
class B {...};
class C : public A, public B {...};
C c;
B* b = &c
在C内部,A应该放在B的顶部,那么指针b如何知道在C中从哪里开始寻址?
【问题讨论】:
-
因为编译器知道A的大小。如果你输出这两个指针你会看到指针的值已经改变了。试试
cout << (void*)&c << ' ' << (void*)b << '\n'; -
@john 地址不会改变。他们应该打印同样的东西。编辑:哦,如果他们有虚拟方法,你的意思是?是的,那么它们会有所不同。
-
它没有。基类定义指定了它有哪些虚函数。当指向的对象是派生类的实例时,实现(也称为编译器)确保所有虚函数调用都解析为最派生类的覆盖。实际上,实现通常使用包含(以某种形式)指向所有虚函数的指针的虚函数表(vtables)。在构造派生类的实例时,基类的 vtable 会填充派生类的条目(因为“派生”部分的构造发生在“基”部分之后)
-
@TedLyngmo
static_cast<A*>(&c)和static_cast<B*>(&c)中的至少一个必须与&c不同,因为A和B子对象必须具有不同的地址。 -
@molbdnilo 是的,如果他们有虚拟方法的话。如果他们没有,他们将有相同的地址。
标签: c++ pointers inheritance memory