为什么派生类成员的初始化值转换为基指针时不会丢失?

时间:2019-03-19 07:17:41

标签: c++ c++11 polymorphism

在下面的代码中,我期望类b的{​​{1}}成员的值会丢失,因为我将其分配给了没有任何成员的基本指针B A。但是它似乎存储在某个地方,最后一行中我仍然得到正确的值30。

我没想到这一点。有人可以解释一下如何在内存中进行管理吗?

这是否意味着当我们分配派生类成员时,所有成员都在内存中,并且它们的可访问性取决于是否使用基类指针来访问该成员?

b

输出

#include <iostream>

using namespace std;

class A {
public:
    A(): a(5) {}
    A(int val): a(val) {}
    int a;
    virtual void f() {}
};

class B: public A {
public:
    B(): a(5), b(10) {}
    B(int val1, int val2): a(val1), b(val2) {}
    int a;
    int b;
    virtual void f() {
        cout<<"Dummy";
    }
};

int main(int argc, char **argv)
{
    A *a = new B(20, 30);
    cout<<"a->a: "<<a->a<<endl;
    B *b = dynamic_cast<B*>(a);
    cout<<"b->a: "<<b->a<<" | b->b: "<<b->b;
    return 0;
}

1 个答案:

答案 0 :(得分:2)

它没有丢失,因为对象仍然是B类型。您在a中添加的额外B是与a中的A完全不同的成员,并且b成员跟随它。指针仅指向您创建的完整A对象的B子对象。从概念上讲,它看起来像这样:

    +--------------------+
    +------+      |      |
a-->| A::a | B::a | B::b |
    +------+      |      |
    +--------------------+

您看到打印值5是因为您的密码:

B(int val1, int val2): a(val1), b(val2) {}

未为A的{​​{1}}基指定初始化程序。因此它是默认初始化的,因此默认的c'tor(将B设置为5的那个)就是被调用的那个。

A::a访问b->a的值,因为您确实使用了B::a指针,这会影响名称查找的工作方式。