多态的基本语法
多态是C++面向对象三大特性之一
1、多态分为两类
静态多态: 函数重载 和 运算符重载属于静态多态,复用函数名
动态多态: 派生类和虚函数实现运行时多态
2、多态满足条件:
1、有继承关系
2、子类重写父类中的虚函数
3、多态使用条件
父类指针或引用指向子类对象
4、重写
函数返回值类型 函数名 参数列表 完全一致称为重写
纯虚函数和抽象类
在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容
因此可以将虚函数改为纯虚函数
语法:virtual 返回值类型 函数名 (参数列表)= 0 ;
=0是纯说明符,不可以为其他的(例如“=1”“=2”)
当类中有了纯虚函数,这个类也称为抽象类
抽象类特点:
- 无法实例化对象
- 子类必须重写抽象类中的纯虚函数,否则也属于抽象类
步骤
1、父类写纯虚函数
class Base{
public:
virtual void func() = 0;
};
2、子类重写纯虚函数(一定要重写,否则没有意义)
class Son :public Base{
public:
virtual void func(){
cout << "func调用" << endl;
};
};
3、运用多态实例化对象
void test(){
Base* base =new Son;//父类虽然无法实例化对象但可以利用引用指向子类对象
base->func();
delete base;//局部变量在堆区,记得销毁
}
虚析构和纯虚析构
多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码
解决方式:将父类中的析构函数改为虚析构或者纯虚析构
虚析构和纯虚析构共性:
- 可以解决父类指针释放子类对象
- 都需要有具体的函数实现
虚析构和纯虚析构区别:
- 如果是纯虚析构,该类属于抽象类,无法实例化对象
虚析构语法:
virtual ~类名(){}
纯虚析构语法:
virtual ~类名() = 0;
类名::~类名(){}
class Animal {
public:
Animal(){
cout << "Animal 构造函数调用!" << endl;
}
virtual void Speak() = 0;
virtual ~Animal() = 0;
};
Animal::~Animal(){
cout << "Animal 纯虚析构函数调用!" << endl;
}
#include <iostream>
using namespace std;
#include <string>
class Animal {
public:
Animal(){
cout << "Animal 构造函数调用!" << endl;
}
virtual void Speak() = 0;
virtual ~Animal() = 0;
};
Animal::~Animal(){
cout << "Animal 纯虚析构函数调用!" << endl;
}
class Cat : public Animal {
public:
Cat(string name){
cout << "Cat构造函数调用!" << endl;
m_Name = new string(name);
}
virtual void Speak(){
cout << *m_Name << "小猫在说话!" << endl;
}
~Cat(){
cout << "Cat析构函数调用!" << endl;
if (this->m_Name != NULL) {
delete m_Name;
m_Name = NULL;
}
}
public:
string* m_Name;
};
void test(){
Animal* animal = new Cat("Tom");
animal->Speak();
delete animal;
}
int main() {
test();
system("pause");
return 0;
}