C++继承:派生类的虚方法不被调用[重复]
Posted
技术标签:
【中文标题】C++继承:派生类的虚方法不被调用[重复]【英文标题】:C++ inheritance: the virtual method of the derived class is not called [duplicate] 【发布时间】:2012-08-20 08:32:58 【问题描述】:可能重复:Store two classes with the same base class in a std::vector
我在 C++ 中遇到了继承问题。这里我写了一个简单的代码来说明我的问题:
//Animal.h
class Animal
public:
Animal();
~Animal();
virtual const void Eat();
;
//Bear.h
class Bear: public Animal
public:
Animal();
~Animal();
virtual const void Eat();
;
//Animal.cpp
const void Animal::Eat()
//Bear.cpp
const void Animal::Eat()
//Do something
现在,在另一个类中,我声明了一个应该包含动物的向量,然后我创建了一个 Bear
并将其推送到我的向量中:
std::vector<Animal> a;
Bear b;
a.push_back(b);
现在的问题是,当我遍历我的动物向量并尝试调用 Eat()
时,会调用基类(动物)的 Eat 方法,而不是 Bear
Eat
方法。
即使尝试使用dynamic_cast it
也不起作用:dynamic_cast
失败
dynamic_cast<Bear*>(&a.at(0));
我做错了什么?是因为我缺少拷贝构造函数吗?
【问题讨论】:
看到这个:***.com/questions/8777724/… 【参考方案1】:您必须创建一个包含动物(智能)指针的向量。
对象向量遭受对象切片。
我假设Bear.cpp
中的void Animal::Eat()
是一个错字,否则您的代码将无法编译。
另外,const void
?你想确保你不修改任何东西?
【讨论】:
一个有趣的问题是 C++11(向量使用移动语义)是否仍然存在这个问题。实际上,我认为它应该是“神奇地”修复的。毕竟,那时不应该复制任何动物,但熊按原样(可能包括 vtable)? @Damon 甚至没有受到质疑。当您声明std::vector<Animal>
时,您明确表示您想要 Animal
对象。你将不再拥有熊。
@Damon,试着想想你将如何存储它。 (以及如何实现 operator[])【参考方案2】:
启用多态需要两件事:虚函数和指针。你没有指针。您的 std::vector
必须是 Animal*
的向量(或 C++11 中的 std::unique_ptr),而不是 Animal
。
std::vector<Animal*> a;
Bear b;
a.push_back(b);
a[0] -> eat();
那么,你的熊函数eat()
是Animal::
。纠正它。
另外,析构函数也必须是虚拟的:析构函数调用也必须是多态的。
【讨论】:
我想过切片问题,但我没想到指针会解决问题。谢谢大家,我学到了一些新东西 但我还是很好奇,当我把熊放入动物载体中会发生什么?它是否调用了基本的复制构造函数并放置了动物而不是熊? @ISTB Bear 是动物(因为继承关系)。因此,如果您将 Bear 放入 Animal(而不是 Animal*)就像使 Animal a = b 其中 b 是 Bear:您可以这样做,但是您在 Animal 中仅复制 Bear 的一些信息(它们共有的成员)。真诚地说,我不知道在这种情况下它是否只被称为 Animal 的构造函数,或者它是否被称为 Bear 的构造函数,然后我们在 Animal 中拥有 Bear 的部分副本,正如我所说的。结果是一样的:你没有 Bear 而是 Animal:所以调用 Animal 的 eat()。 是的,我认为首先调用 Animal 构造函数,然后调用复制构造函数,它当然只复制熊的“动物”信息而不是熊信息以上是关于C++继承:派生类的虚方法不被调用[重复]的主要内容,如果未能解决你的问题,请参考以下文章