0 介绍
本文主要总结:多态,虚函数,虚析构,虚表指针,虚函数与继承关系,纯析构函数,纯虚函数之间的相互关系。
C++ 三大主要特性:封装,继承,多态。多态定义:接口的多种不同的实现方式.
多态的分类有两种:编译时多态和运行时多态。
编译时多态:函数重载或运算符重载实现
运行时多态:通过Vritual实现
作用:同一操作可以有不同的表现,简化代码;
1 虚函数定义
1.1 定义实现
格式: virual 返回值类型 函数名(参数列表);
类外实现不需加virtual关键字。
virtual实现多态的三个条件:1 继承关系 2 需要是虚函数 3 父类指针或引用指向子类对象
当一个类的函数是虚函数,则它的子类就是虚函(可以不用添加virtual关键字)
a: c++类对象的赋值规则向上兼容规则;对于子类指针指向子类对象或子类引用子类对象,则调用的子类函数;若基类指针或基类引用指向基类对象或引用,则调用基类函数;只有在基类指向或引用子类对象才能形成多态。
b:若基类函数为虚函数,则只要继承了它的子类,整个继承体系此函数都是虚函数,子类可以不需写vritual
#include <iostream>
using namespace std;
//基类
class Base
{
public:
void Show(){
cout <<" This is Base show()" <<endl;
}
virtual void Print(){
cout <<" This is Base print()" <<endl;
}
};
//子类
class Sub : public Base
{
public:
void Show(){
cout << " This is Sub show() " <<endl;
}
virtual void Print(){
//虚函数可不写
cout <<" This is sub print()" <<endl;
}
};
int main()
{
//类向上赋值兼容规则 (子类可赋值基类对象,反之不可)
Base base;
Sub sub;
cout << "=========对象赋值========" <<endl;
//1 对象复制
base = sub;
base.Show();
base.Print();
cout << "=========指针赋值========" <<endl;
//2 指针赋值
Sub z_sub;
Base *z_base = &z_sub;
z_base->Show();
z_base->Print();
cout << "=========引用赋值========" <<endl;
//3 引用赋值
Sub y_sub;
Base &y_base = y_sub;
y_base.Show();
y_base.Print();
return 0;
}
运行结果:
1.2 虚函数特例
特例:virtual多态是需要虚函数函数返回值和函数名,函数参数列表都需要相同;但是有一个特例如下 也可以形成多态
#include <iostream>
using namespace std;
//基类
class Base
{
public:
virtual Base* Show()
{
cout << " This is Base show() " <<endl;
return this;
}
};
//子类
class Sub : public Base
{
public:
Sub* Show() //返回值和基类的类型不一致
{
cout <<" This Is Sub show()" << endl;
return this;
}
};
int main()
{
Sub sub;
Base *pb = ⊂
pb->Show();
return 0;
}
运行结果:
全局函数,静态成员函数,内联函数,构造函数不能设置为virutal函数;而成员函数和析构函数可以设置为virtual函数
1.3 虚析构函数
动态分配内存(如 Base *pb = new Sub; ),基类指针指向子类对象;开辟空间的时候会先构造父类对象,然后又构造了一个完整的子类对象;但是释放的时候只会释放调用父类的析构函数,而子类的析构函数未释放。
将父类的析构函数定义为虚函数,则形成多态,可以级联调用析构函数释放内存
#include <iostream>
using namespace std;
//析构函数定义为虚函数
class