C ++中的多态和虚拟

Ric*_*rdo 2 c++ polymorphism virtual inheritance

我对C ++中的多态感到困惑。我正在自己研究它,并且了解它的主要功能。但是我不明白为什么会有帮助。在研究多态性(关于oop)之前,我研究了继承(这很有用,因为您只能在一次超类和子类的编写中使用一个方法)。现在,我被多态性和virtual关键字所困扰。我不明白为什么会有帮助。请参阅下面的代码(这是有关C ++研究所的练习(我将获得认证))。为什么可以将仅虚函数声明为“虚”函数?我添加的代码中的变量n1n2n3(公开),为什么我不能访问它们?我根本不了解多态性,我在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();
}
Run Code Online (Sandbox Code Playgroud)

Fre*_*son 7

也许一个例子会有所帮助。考虑一个不同的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();
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们有一堆宠物。我们可以用相同的方式处理它们,但是它们发出不同的声音。召唤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!
Run Code Online (Sandbox Code Playgroud)

现在,尝试删除virtual关键字,它们都将显示“嘘!嘘!”。