cpp_polymorphism - ShenYj/ShenYj.github.io GitHub Wiki

多态

简介

  • 父类指针可以指向子类对象,是安全的,开发中经常用到(继承方式必须是public)

    struct Person {
        int m_age;
    };
    
    struct Student: Person {
        int m_score;
    };
    
    int main() {
    
        /// 父类指针指向子类对象
        Person *p = new Student();
    
        getchar();
        return 0;
    }
  • 子类指针指向父类对象是不安全的 (结合内存布局,子类的内存范围往往大于父类,父类指针范围小于子类,所以访问内存时相对安全)

    Student *p = (Student *)new Person();
  • 默认情况下,编译器只会根据指针类型调用对应的函数,不存在多态

  • 多态是面向对象非常重要的一个特性

    • 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果
    • 在运行时,可以识别出真正的对象类型,调用对应子类中的函数
  • 多态的要素

    • 子类重写父类的成员函数(override) 【函数名、返回值、参数 完全一致,默认是不存在多态的,只看指针类型】
    • 父类指针指向子类对象
    • 利用父类指针调用重写的成员函数

虚函数

  • C++中的多态通过虚函数(virtual function)来实现
  • 虚函数:被virtual修饰的成员函数
  • 只要在父类中声明为虚函数,子类中重写的函数也自动变成虚函数(也就是说子类中可以省略virtual关键字)
struct Animal {
    virtual void speak() {
        cout << "Animal::speak()" << endl;
    }
    virtual void run() {
        cout << "Animal::run()" << endl;
    }
};

struct Dog : Animal {

    override void speak() {
        cout << "Dog::speak()" << endl;
    }
    override void run() {
        cout << "Dog::run()" << endl;
    }
};

struct Cat : Animal {
    void speak() {
        cout << "Cat::speak()" << endl;
    }
    void run() {
        cout << "Cat::run()" << endl;
    }
};

void liu(Animal *p) {
    p->speak();
    p->run();
}

int main() {

    liu(new Dog()); /// Dog::speak() Dog::run()
    liu(new Cat()); /// Cat::speak() Cat::run()

    getchar();
    return 0;
}
⚠️ **GitHub.com Fallback** ⚠️