多态
- 1.多态的概念
- 2.多态的定义和实现
- 2.1多态构成条件
- 2.2虚函数
- 2.3虚函数的重写(覆盖)
- 2.4 C++11 override 和 final
- 2.5重载、重写(覆盖)、隐藏(重定义)的对比
- 3.抽象类
- 4.多态的原理
- 5.单继承和多继承关系的虚函数表
- 5.1单继承
- 5.2多继承
- 5.3菱形继承和多态
1.多态的概念
多态的概念:同样的一个行为,不同的对象去完成时会产生不同的状态。
例子:拿买票举例,军人、学生、普通人(子类)都是人(父类),但军人买票可以优选选票,学生买票可以半价,普通人买票就要全价了。因此要实现多态必先继承。
2.多态的定义和实现
2.1多态构成条件
多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如上面的例子定义父类Person,让子类Student继承Preson。Person对象买票全价,Student对象买票半价。
已经形成了继承关系,实现多态还需要以下两个条件:
- 必须通过基类的指针或者引用调用虚函数
- 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写
大家先记住这两个条件,后面讲解虚函数和多态原理后大家就明白了。
2.2虚函数
虚函数:即被virtual修饰的类成员函数称为虚函数。
class Person { public: //这里和菱形虚拟继承公用了关键字,但两者是没有关联的 virtual void BuyTicket() { cout public: virtual void BuyTicket() { cout public: virtual void BuyTicket() { cout p.BuyTicket(); //因为是父类引用去调用,所以构成多态 } int main() { Person ps; Student st; Func(ps); Func(st); return 0; } }; class B : public A {}; class Person { public: virtual A* f() {return new A;} }; class Student : public Person { public: virtual B* f() {return new B;} }; public: virtual ~Person() { cout public: virtual ~Student() { cout Person* p1 = new Person; Person* p2 = new Student; //如果父类析构不设计为虚函数的话可能造成内存泄漏 delete p1; delete p2; return 0; } public: virtual void Drive() final {} }; class Benz :public Car { public: virtual void Drive() { cout //…… }; class B : public A //这里会报错 {}; public: virtual void Drive() {} }; class Benz :public Car { public: virtual void Drive() override { cout } void fun(double a) {} //隐藏 //两个同名函数在基类和派生类作用域内,不构成重写就属于隐藏 class A { void fun(int a) {} }; class B : public A { void fun(int a) {} }; //重写 //两个同名函数在基类和派生类作用域内,并且都是虚函数 //函数名、参数列表、返回值都必须一致(除去例外),才能构成重写 class C { virtual void fun(int a) {} }; class D : public C { virtual void fun(int a) {} }; public: virtual double GetArea() = 0 {}//抽象类里面可以设计图形共有的接口,比如求面积等 }; class Square : public Graphics //正方形 { public: virtual double GetArea() { return side_length * side_length; } private: int side_length = 5; }; class rotundity : public Graphics //圆形 { public: virtual double GetArea() { return 3.14 * radius * radius; } private: int radius = 5; }; int main() { Square sq; rotundity ro; cout public: virtual void Func1() { cout public: virtual void BuyTicket() { cout public: virtual void BuyTicket() { cout p.BuyTicket(); } int main() { Person Mike; Func(Mike); Student Johnson; Func(Johnson); //这里不构成多态,对象调用而不是指针或引用,按正常调用规则即可 Mike.BuyTicket(); return 0; } public: virtual void fun(int a) {} }; class B { public: virtual void fun(int b) {} }; class C : public A, public B //继承A、B两个类 { public: virtual void fun(int c) {} }; int main() { C c; A* p1 = new C; B* p2 = new C; p1-fun(); p2-fun(); delete p1, p1 = nullptr; delete p2, p2 = nullptr; return 0; }