c++ - 在基类中是 const 而在派生类中不是 const 的虚函数

标签 c++ inheritance virtual constants

谁能解释一下下面代码的输出结果?

#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 中的函数.

结果是调用printMessageAnimal 上将只使用 Animal 中的版本, 无论 Cow 中的那个(它没有覆盖它),而是从 Cow 调用它将使用 Cow 中的那个(因为它隐藏了来自 Animal 的那个)。

要解决此问题,请删除 constAnimal ,或添加 constCow .

在 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; 
    } 
};

注意添加的 overrideprintMessage() 之后.如果 printMessage,这将导致编译器发出错误实际上并没有覆盖基类版本。在这种情况下,您会收到错误消息。

关于c++ - 在基类中是 const 而在派生类中不是 const 的虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7504300/

相关文章:

java - log4j2 pkg 中记录器接口(interface)的继承方法

java - java中的抽象/虚函数

c++ - 如何将一个 "unknown"的派生类声明为基类的成员,并允许派生版本的成员函数被调用?

c++ - 多线程时使用 shared_ptr 进行写时复制

C++ 无法打开文件进行输出

C++ 从方法调用 EXE

c++ - 从基类特定函数调用子类方法

c++ - 为什么 clang-tidy 建议在任何地方添加 [[nodiscard]] ?

c++ - 比较来自两个不同类的对象?

c# - 为什么我不能将 set 访问器添加到覆盖属性?