c++入门经典学习笔记 17.1使用虚函数实现多态

多态:多种形态
#include <iostream>
  
class Mammal
{
public:
    Mammal():age(1) { std::cout << "Mammal constructor ...\n"; }
    ~Mammal() { std::cout << "Mammal destructor ...\n"; }
    void move() const { std::cout << "Mammal, move one step\n"; }
    virtual void speak() const { std::cout << "Mammal speak!\n"; }
  
protected:
    int age;
};
  
class Dog : public Mammal
{
public:
    Dog() { std::cout << "Dog constructor ...\n"; }
    ~Dog() { std::cout << "Dog destructor ..\n"; }
    void wagTail() { std::cout << "Wagging tail ...\n"; }
    void speak() const { std::cout << "Woof!\n"; }
    void move() const { std::cout << "Dog moves 5 steps ...\n"; }
};
  
int main()
{
    Mammal *pDog = new Dog;
    pDog->move();
    pDog->speak();
    return 0;
}

其中,Mammal *pDog=new Dog,创建一个mammal类型的指针,所以使用Move时是调用的mammal中的Move( ),由于speak是虚函数,所以调用dog中重写的speak。

#include <iostream>
  
class Mammal
{
public:
    Mammal():age(1) {  }
    ~Mammal() { }
    virtual void speak() const { std::cout << "Mammal speak!\n"; }
protected:
    int age;
};
  
class Dog : public Mammal
{
public:
    void speak() const { std::cout << "Woof!\n"; }
};
  
class Cat : public Mammal
{
public:
    void speak() const { std::cout << "Meow!\n"; }
};
  
class Horse : public Mammal
{
public:
    void speak() const { std::cout << "Whinny!\n"; }
};
  
class Pig : public Mammal
{
public:
    void speak() const { std::cout << "Oink!\n"; }
};

int main()
{
    Mammal* array[5];
    Mammal* ptr;
    int choice, i;
    for (i = 0; i < 5; i++)
    {
        std::cout << "(1) dog (2) cat (3) horse (4) pig: ";
        std::cin >> choice;
        switch (choice)
        {
        case 1: 
            ptr = new Dog;
            break;
        case 2: 
            ptr = new Cat;
            break;
        case 3: 
            ptr = new Horse;
            break;
        case 4: 
            ptr = new Pig;
            break;
        default: 
            ptr = new Mammal;
            break;
        }
        array[i] = ptr;
    }
    for (i=0; i < 5; i++)
    {
        array[i]->speak();
    }
    return 0;
}

创建一个 mammal 指针数组,每个元素存放的是 mammal 对象的指针,如 pig dog... 什么的,mammal中的speak为虚函数,所以调用派生类中的speak。

在编译阶段,不知道将要创建什么类型的对象,因此无法知道要调用哪个speak方法,ptr指向的对象是在运行阶段确定的,这被称为后期绑定(类似与new的动态内存?)或运行阶段绑定,与此相对的是静态绑定和编译阶段绑定

猜你喜欢

转载自blog.csdn.net/suyunzzz/article/details/89946108