虚函数
是实现多态
特性的重要工具. 下面看一个例子体会一下:
class base {
public:
virtual void show() { std::cout << "base" << std::endl; };
virtual ~base() { std::cout << "base destruct" << std::endl; }
};
class derive : public base {
public:
void show() { std::cout << "derive" << std::endl; };
~derive() { std::cout << "derive destruct" << std::endl; }
};
int main(void) {
derive der;
base *d = &der;
d->show();
std::cout << "exit" << std::endl;
}
输出:
derive
exit
derive destruct
base destruct
通过基类
的指针指向派生类
的地址, 在调用基类
对象时, 动态选择其真实类型关联的函数, 从而实现多态特性
.
- 构造函数为什么不能是虚函数?
虚函数
的主要目的是通过基类
的指针或引用, 调用派生类
关联的函数, 实现多态
特性. 而构造函数是在初始化一个对象时调用的,派生类
此时并没有完全构造出来(调用构造函数前), 也没有与对应的基类
指针或引用关联起来, 没有办法使用多态
特性. 构造函数是虚函数
没有必要. - 虚构函数为什么可以是虚函数?
因为释放堆上内存时可能通过基类
的指针进行delete
, 如果析构函数不是虚函数
, 则会调用基类的析构函数,派生类
就得不到正确的销毁, 造成内存泄露. 一般在使用多态
特性时,基类
的析构函数都应是虚函数
. 虚函数
的默认参数是静态绑定的. 即, 通过基类
的指针访问派生类
时, 传入的是基类
的默认参数, 而不是派生类
的默认参数.虚函数
可以是私有的, 只要在动态绑定时能绑定即可. 例如:基类
的虚函数是私有的,派生类
的虚函数是公有的, 则通过基类
的指针或引用访问派生类
的方法时, 并不会存在找不到函数的错误.
纯虚函数
纯虚函数
简单来说就是没有定义的虚函数
. 写法就是在虚函数
后添加= 0
修饰. 下面看一个例子:
class base {
public:
virtual void show() = 0;
virtual ~base() { std::cout << "base destruct" << std::endl; }
};
class derive : public base {
public:
void show() { std::cout << "derive" << std::endl; };
~derive() { std::cout << "derive destruct" << std::endl; }
};
int main(void) {
derive der;
base *d = &der;
d->show();
std::cout << "exit" << std::endl;
}
那纯虚函数
有什么用呢? 纯虚函数
一般用于实现抽象类
. 那什么是抽象类
呢? 抽象类
简单来说就是接口
, 通过定义一些共同行为
的集合, 对派生类
进行约束. 当然抽象类
也可以有数据成员. 那抽象类有什么特点呢?
- 抽象类不能实例化, 一般使用指针或引用实现
多态
特性. - 只要有一个
纯虚函数
, 该类就是抽象类. - 抽象类的所有虚函数(析构函数除外), 必须在
派生类
中实现, 才能成为非抽象类
, 否则派生类
也是抽象类
. 抽象类
可以有构造函数.抽象类
的构造函数一般被派生类
调用, 初始化抽象类
的数据成员.
如果觉得有帮助,可以扫描右边的微信打赏码支持一下.