谁能解释一下下面代码的输出结果?
#include <iostream>
#include <string>
class Animal
{
public:
Animal(const std::string & name) : _name(name) { }
~Animal() { }
virtual void printMessage() const
{
std::cout << "Hello, I'm " << _name << std::endl;
}
private:
std::string _name;
// other operators and stuff
};
class Cow : public Animal
{
public:
Cow(const std::string & name) : Animal(name) { }
~Cow() { }
virtual void printMessage()
{
Animal::printMessage();
std::cout << "and moo " << std::endl;
}
};
int main() {
Cow cow("bill");
Animal * animal = &cow;
cow.printMessage();
animal->printMessage();
}
输出是
Hello, I'm bill
and moo
Hello, I'm bill
我不明白为什么。指针 animal 指向 Cow 类型的对象。 printMessage 是一个虚函数。为什么 Cow 类的实现不是被调用的那个?
最佳答案
Cow
没有覆盖 Animal
中的虚函数因为它有不同的签名。实际发生的是 Cow
隐藏 Animal
中的函数.
结果是调用printMessage
在 Animal
上将只使用 Animal
中的版本, 无论 Cow
中的那个(它没有覆盖它),而是从 Cow
调用它将使用 Cow
中的那个(因为它隐藏了来自 Animal
的那个)。
要解决此问题,请删除 const
在 Animal
,或添加 const
在 Cow
.
在 C++ 2011 中,您将能够使用 override
避免像这样的微妙陷阱的关键字:
class Cow : public Animal
{
public:
Cow(const std::string & name) : Animal(name) { }
~Cow() { }
virtual void printMessage() override
{
Animal::printMessage();
std::cout << "and moo " << std::endl;
}
};
注意添加的 override
在 printMessage()
之后.如果 printMessage
,这将导致编译器发出错误实际上并没有覆盖基类版本。在这种情况下,您会收到错误消息。
关于c++ - 在基类中是 const 而在派生类中不是 const 的虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7504300/