azp*_*are 8 c++ virtual inheritance const
任何人都可以解释以下代码的输出?
#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();
}
Run Code Online (Sandbox Code Playgroud)
输出是
你好,我是账单
和moo
你好,我是账单
我不明白为什么.指针动物指向Cow类型的对象.printMessage是一个虚函数.为什么Cow类的实现不是被称为的?
Pet*_*der 13
Cow不会覆盖虚函数,Animal因为它具有不同的签名.什么是实际发生的情况是Cow被隐藏的功能Animal.
这样做的结果是调用printMessage一个Animal将只使用版本Animal,不管Cow它是什么(它没有覆盖它),但调用它将Cow使用中的那个Cow(因为它隐藏了一个Animal).
要解决此问题,请删除constin Animal或添加constin 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;
}
};
Run Code Online (Sandbox Code Playgroud)
注意添加override后printMessage().如果printMessage实际上没有覆盖基类版本,这将导致编译器发出错误.在这种情况下,您将收到错误.
你有两个不同的版本printMessage,一个是const一个,一个不是.这两者是无关的,即使它们具有相同的名称.新函数Cow隐藏了一个Animal,所以当你直接调用它时,编译器只考虑Cow版本.