c++ - C++ 中的多态性和虚函数

标签 c++ inheritance polymorphism virtual

我对 C++ 中的多态性感到困惑。我自己在研究它,我了解它的主要特点。但我不明白为什么它有帮助。在研究多态(关于oop)之前,我研究了继承(这很有帮助,因为你可以在父类(super class)和子类中使用一个方法只写一次)。现在我受困于多态性和 virtual 关键字。我不明白为什么它有帮助。请参见下面的代码(这是一个关于 C++ 研究所的练习(我将获得认证))。为什么我只能声明为“虚拟”功能?我在代码中添加了变量 n1n2n3(作为公共(public)变量),为什么我不能访问它们?我完全不了解多态性,我在 StackOverflow 上阅读了大量关于多态性的帖子,但好像我对多态性的了解只有 50%。我注意到多态性在 python 中不那么难理解,因为 python 没有数据类型,但我也想在 C++ 中理解它,以及它的可能用途。

#include <iostream>
using namespace std;
class Pet {
    protected:
    string Name;
    public:
    Pet(string n) { Name = n; }
    virtual void MakeSound(void) { cout << Name << " the Pet says: Shh! Shh!"  << endl; }
    int n1;
};
class Cat : public Pet {
    public:
    Cat(string n) : Pet(n) { }
    void MakeSound(void) { cout << Name << " the Cat says: Meow! Meow!" <<       endl; }
    int n2;
};
class Dog : public Pet {
    public:
    Dog(string n) : Pet(n) { }
    void MakeSound(void) { cout << Name << " the Dog says: Woof! Woof!" << endl; }
    int n3;
};
int main(void) {
    Pet* a_pet1, * a_pet2;
    Cat* a_cat;
    Dog* a_dog;

    a_pet1 = a_cat = new Cat("Kitty");
    a_pet2 = a_dog = new Dog("Doggie");

    a_pet1->MakeSound();
    a_cat->MakeSound();
    static_cast<Pet*>(a_cat)->MakeSound();
    a_pet2->MakeSound();
    a_dog->MakeSound();
    static_cast<Pet*>(a_dog)->MakeSound();
}

最佳答案

也许一个例子可以提供帮助。考虑一个不同的 main(),像这样:

int main()
{
    std::vector<std::unique_ptr<Pet>> menagerie;
    menagerie.push_back(std::make_unique<Dog>("Fido"));
    menagerie.push_back(std::make_unique<Cat>("Morris"));
    menagerie.push_back(std::make_unique<Cat>("Garfield"));
    menagerie.push_back(std::make_unique<Dog>("Rover"));

    for (auto&& pet : menagerie)
    {
        pet->MakeSound();
    }
}

这里我们有一堆宠物。我们可以用同样的方式处理它们,但它们会发出不同的声音。对每个调用 MakeSound 对特定种类的宠物都是正确的。这种用例很常见。

Fido the Dog says: Woof! Woof!
Morris the Cat says: Meow! Meow!
Garfield the Cat says: Meow! Meow!
Rover the Dog says: Woof! Woof!

现在,尝试删除 virtual 关键字,他们都会说“嘘!嘘!”。

关于c++ - C++ 中的多态性和虚函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57332139/

相关文章:

c++ - 引用嵌套模板参数

c++ - 遍历 Base 类型的 vector 和/或从 base 派生的类型

c# - 方法重载和多态性

function - 将继承的帧作为参数传递给过程

c++ - 通过基本引用进行分配的对象切片是否定义良好?

c++ - 哪种转换技术更适合在 C++ 中从上层到下层进行转换

java - 作为子类的动态类型转换

c++ - 在 C++ 中使用逻辑作为参数

c++ - 如何将 vector (或不同的容器)与不可复制的类一起使用?

C++ 继承以及如何通过父类(super class)传递和维护子类数据