前面学习了多态底层原理和多态练习,这篇学习什么是纯虚函数和抽象类。虚函数前面我们介绍过,一个普通的类成员函数前面添加关键字virtual就变成一个虚函数。会有虚函数指针指向虚函数列表的概念,这里纯虚函数肯定和虚函数是有关系的。
1.虚函数的定义
语法是 virtual 返回值类型 函数名称() = 0;
例如,下面这个代码
class Base
{
public:
virtual void myFunc() = 0;
};
一般来说,在使用多态机制的时候,基类中的虚函数里面没不需要写什么实现,因为写了也很少用到。就前面动物的例子,虚函数打印 动物在叫,但是我们一般都是打印 猫在叫或者狗在叫,一般是派生类的同名函数中实现才是我们关心的内容。
既然虚函数内部函数体没有啥作用,所以就产生了纯虚函数,写法就像上面这个样子。也就是在原来虚函数改成,删除{}这大括号里面内容,直接在函数名称后写 = 0;
2.抽象类的定义
在一个类中,只要有一个纯虚函数,那么这个类就叫抽象类。
class Base
{
public:
virtual void myFunc() = 0;
};
上面这个类,由于有一个纯虚函数,所以Base类就是一个抽象类。抽象的字面意思就是抽出象的东西,一般这种抽取的东西都不详细,不清晰,所以抽象。
3.抽象类特点
3.1 抽象类不能被实例化
就是不能在栈内存或堆内存创建抽象类的对象
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
virtual void myFunc() = 0;
};
void test01()
{
Base b; // 栈内存创建Base对象
new Base(); //堆内存创建Base对象
}
在上面函数 test01中两种创建对象的方式都失败,编译器提出错误
3.2 子类必须实现基类的纯虚函数
如果一个抽象类被一个派生类继承,那么在派生类中必须要实现纯虚函数。
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
virtual void myFunc() = 0;
};
class Son : public Base
{
public:
};
void test01()
{
Son s;
}
int main()
{
test01();
system("pause");
}
上面子类没有实现父类的纯虚函数,在子类实例化的时候会报错。
由于没有实现父类的纯虚函数,那么子类也变成一个抽象类,有回到上抽象类不能实例化的问题。
接下来看看,正常子类实现父类纯虚函数的代码
#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
virtual void myFunc() = 0;
};
class Son : public Base
{
public:
void myFunc()
{
cout << "子类必须实现父类的纯虚函数" << endl;
}
};
void test01()
{
Base * b = new Son;
b->myFunc();
}
int main()
{
test01();
system("pause");
}
运行结果(VS code截图)