我想为我的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;
};
现在,通过在Base
或ChildA
的指针上调用getA()
,您将得到 1,但在类型ChildB
的对象上调用getA
将返回 2。