C/C++总述:Study C/C++-CSDN博客
目录
对于同一个行为对于不同的对象,有不同的表现。
eg:买票这个行为,当普通人买票时,是全价买票;学生买票时,是半价买票;军人 买票时是优先买票。
多态在 c++ 中分为 静态多态 与 动态多态,也称 编译期多态 和 运行时多态 。
静态多态:是基于 函数重载 与 泛型编程 实现的。
动态多态:是基于虚函数实现的。
- class Person {
- public:
- virtual void BuyTicket() { cout << "买票-全价" << endl;}
- };
- class Person { //多态条件2:被调用的函数 必须是虚函数
- public:
- virtual void BuyTicket() { cout << "买票-全价" << endl; }
- };
-
- class Student : public Person {
- public: //多态条件2:派生类必须对基类的虚函数进行重写
- virtual void BuyTicket() { cout << "买票-半价" << endl; }
- /*注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因
- 为继承后基类的虚函数被继承下来了在派生类依旧保持虚函数属性),但是该种写法不是很规范,不建议
- 这样使用*/
- /*void BuyTicket() { cout << "买票-半价" << endl; }*/
- };
-
- void Func(Person& p) //多态条件1:必须通过基类的指针来“引用”调用虚函数
- {
- p.BuyTicket();
- }
-
- int main()
- {
- Person ps;
- Student st;
-
- Func(ps); //输出:买票-全价
- Func(st); //输出:买票-半价
-
- return 0;
- }
派生类重写基类虚函数时 ,与基类虚函数 返回值类型不同 。即如下代码所示:【基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用时】,称为协变。
- class A{};
- class B : public A {};
-
- class Person
- {
- public:
- virtual A* f() {return new A;}
- };
-
- class Student : public Person
- {
- public:
- virtual B* f() {return new B;}
- };
如果 基类的析构函数为虚函数 ,此时派生类析构函数只要定义,无论是否加virtual关键字,都与基类的析构函数构成重写,虽然基类与派生类析构函数名字不同。 虽然函数名不相同~Person() ,~Student() ,看起来违背了重写的规则,其实不然,这里可以理解为编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成 destructor 。
- class Person
- {
- public: //基类的析构函数为虚函数
- virtual ~Person() {cout << "~Person()" << endl;}
- };
-
- class Student : public Person
- {
- public:
- virtual ~Student() { cout << "~Student()" << endl; }
- };
- //只有派生类Student的析构函数重写了Person的析构函数,下面的delete对象调用析构函数,才能构成多态,才能保证p1和p2指向的对象正确的调用析构函数。
- int main()
- {
- Person* p1 = new Person;
- Person* p2 = new Student;
-
- delete p1;
- delete p2;
-
- return 0;
- }
final:修饰虚函数,使虚函数不能被覆盖。(加在父类中)
final修饰类时,表示这个类不能被继承。
override:修饰虚函数,检测是否正确覆盖。(加在子类中)
- class A
- {
- public:
- virtual void test()final //使该虚函数不能覆盖,若被覆盖就报错
- {}
- }
-
- class B: public A
- {
- public:
- virtual void test()override //检查虚函数是否正确覆盖,若未覆盖就报错
- {}
- }
含纯虚函数的类,称为抽象类
- class Car // 抽象类
- {
- public:
- virtual void Drive() = 0; //在虚函数的后面写上 =0,这个函数为 纯虚函数
- };
-
- class Benz :public Car
- {
- public:
- virtual void Drive()
- {
- cout << "Benz-舒适" << endl; //只有 重写纯虚函数 ,派生类才能实例化出对象
- }
- };
-
- class BMW :public Car
- {
- public:
- virtual void Drive()
- {
- cout << "BMW-操控" << endl;
- }
- };
-
-
- void Test()
- {
- Car* pBenz = new Benz;
- pBenz->Drive();
-
- Car* pBMW = new BMW;
- pBMW->Drive();
- }