初始化和修改派生类中的类变量



我想为我的Base类初始化一个变量类,并仅在某些子类中修改它。
此类变量的初始化在标头中:

class Base{
public:
Base();
int a = 1;

我的派生类的标头是:

class ChildA : public Base{
public:
ChildA ();
int a = 2;
}

问题

我试图运行这个:

Base classe*;
classe = new ChildA();
std::cout << classe->a << std::endl;

问题是,它没有像我预期的那样打印2,而是打印1(在我的父类中初始化的值(。对于其他派生类,我希望classe->a仍然返回1。 我该如何解决这个问题?

您看到的是向上转换的结果 - 将基类指向派生类对象。

我强烈建议您阅读有关该主题的更多信息,但简化的图片是基类"携带"整个对象(基和派生内容(,但只能访问其原始的、自己的内容。这就是您看到基类而不是派生类a值的原因。

Lippman 的 C++ Primer 对上投、下投、对象切片和其他与继承相关的概念进行了非常全面的解释。这包括实现虚拟函数,这些函数为您提供了通过 base 通用的接口调用派生类函数的功能。

|----------------|-----------------|
| a (for Base)   | a (for ChildA)  |
|----------------|-----------------|
________________/
^
|_ classe

对不起,如果我的画不是那么好!如上图所示,当您创建一个类型ChildA的对象时,该对象包含一个用于保存基类的数据成员的部分(即Base(和另一部分用于派生类的数据成员(即ChildA(。考虑到您有一个指向基类的指针(即classe(,此指针仅允许您访问基本成员变量和方法。所以调用classe->a,为你返回Base::a,即 1。

如果将classe指针的类型更改为ChildA,在这种情况下,调用classe->a将返回 2,因为它引用派生类中的a,即ChildA::a.

对于其他派生类,我希望classe->a仍然返回1。怎么能 我解决了这个?

如果你需要在某些派生类中访问不同的a,最好在基类中有一个虚函数,并在需要时覆盖基函数:

class Base {
public:
Base() {}
virtual int getA() { return a; }
private:
int a = 1;
};
class ChildA : public Base 
{
public:
ChildA() {}
int a = 2;
};
class ChildB : public Base
{
public:
ChildB() {}
int getA() { return a; }
private:
int a = 2;
};

现在,通过在BaseChildA的指针上调用getA(),您将得到 1,但在类型ChildB的对象上调用getA将返回 2。

最新更新