1.多态的概念
同一件事物,在不同场景下表现出的不同的状态
举例:买票行为,学生半价,普通人全价,军人优先
分类:静态多态和动态多态
静态多态:编译器在编译时确定具体调用哪个函数。体现:函数重载,模板动态多态:编译时无违法确定调用哪个函数,只有在代码运行时才知道具体应该调用哪个函数 体现:虚函数+重写
- 动态多态的实现
2.1C++中实现多态的条件>>在继承体系中,基类中必须有虚函数,派生类必须对基类中的虚函数进行重写>>必须通过基类的指针或引用去调用虚函数体现:基类的 指针或引用指向哪个类的对象,程序运行时就会调用哪个类的虚函数
#include<iostream>
#include<string>
using namespace std;
class person {
public:
virtual void BuyTicket() {
cout << "全价购票" << endl;
}
protected:
string _name;
string _dender;
int _age;
};
class student:public person {
public:
virtual void BuyTicket() {
cout << "半价购票" << endl;
}
};
void Test(person&p){
p.BuyTicket();
}
int main() {
person p;
Test(p);
student s;
Test(s);
return 0;
}
2.2 重写
派生类重写基类的虚函数,必须保证派生类虚函数的原型(函数名,返回值类型,参数列表)与基类的虚函数完全一致,虚函数的重写也叫做虚函数的覆盖
例外:协变–基类的虚函数返回基类的指针或引用,派生类的虚函数返回派生类的指针或引用(返回值类型不同)
#include<iostream>
using namespace std;
class A
{
};
class B:public A
{
};
A a;
B b;
class person {
public:
virtual A& BuyTicket() {
cout << "全价购票" << endl;
return a;
}
};
class student :public person {
public:
virtual B& BuyTicket() {
cout << "半价购票" << endl;
return b;
}
};
void Test(person& p) {
p.BuyTicket();
}
int main() {
person p;
student s;
Test(p);
Test(s);
return 0;
}
析构函数的重写–只要基类的析构函数给成虚函数,派生类的析构函数一旦显式提供,就可以构成重写(函数名不同)
#include<iostream>
using namespace std;
class person {
public:
virtual ~person() {
cout << "person::~person" << endl;
}
};
class student :public person {
public:
virtual ~student() {
cout << "student::~student" << endl;
}
};
int main() {
person* p1 = new person;
delete p1;
p1 = new student;
delete p1;
return 0;
}
3.c++11关键字override和final
override修饰派生类虚函数强制完成重写,如果没有重写会编译报错
#include<iostream>
using namespace std;
class person {
public:
virtual void TestFunc() {
cout << "person::TestFunc()" << endl;
}