【Effective C++】条款7:为多态基类声明virtual析构函数
2023-12-13 03:51:00
如果你实现的一个类打算作为基类,并且要实现多态,那么就应该将析构函数声明为virtual。
class TimeKeeper
{
public:
TimeKeeper();
~TimeKeeper();
};
TimeKeeper::TimeKeeper()
{
cout << "TimeKeeper构造" << endl;
}
TimeKeeper::~TimeKeeper()
{
cout << "TimeKeeper析构" << endl;
}
class AtomicClock : public TimeKeeper
{
public:
AtomicClock();
~AtomicClock();
};
AtomicClock::AtomicClock()
{
cout << "AtomicClock构造" << endl;
}
AtomicClock::~AtomicClock()
{
cout << "AtomicClock析构" << endl;
}
int main()
{
TimeKeeper* ptr = new AtomicClock;
delete ptr;
return 0;
}
可见,父类指针指向子类对象时,当用该指针去调用析构函数,实际上调用的是父类的析构函数,这会导致子类中自己的那部分资源没有得到处理。
解决方案:将父类的析构函数声明为virtual?
virtual ~TimeKeeper();
简单说一下原理:
如果一个类有成员函数是虚函数,那么编译器将会为该类生成一张虚表,存放该类的虚函数地址。
实例化的对象中会额外增加一个虚表指针vptr,该指针指向虚表。
当用父类指针调用虚函数时,从指向的对象中拿到虚表指针,到虚表中找到该类的虚析构函数,再去调用。
你只需记住:任何具有虚函数的类都应有虚析构函数。因为虚函数就是为了实现多态,多态就可能出现上面的情况。
提示一下,多态基类的析构函数要加virtual,子类可加可不加,因为不管你加不加,它都是virtual的。
当一个类不打算成为多态基类时,就不应将析构函数设为虚函数。
原因很简单,因为有虚函数的类实例出的对象中,会额外增加一个指针浪费空间。
STL中的很多类都没有虚析构函数,不要随意继承它们,否则容易出问题
?如果你想要一个抽象类(不能实例化对象),但没有任何纯虚函数时,可以声明一个纯虚析构函数。但是,你必须为该析构函数提供定义。
class AWOV
{
public:
virtual ~AWOV() = 0;
};
AWOV::~AWOV()
{}
?
纯虚函数的目的就是要求它的子孙类都提供这样一个接口,是为了实现规范,而不是用来调用的,所以一般不用给出定义。但纯虚析构函数必须给出定义,因为子类对象析构时会调用父类的析构函数,如果不提供定义会链接错误。
文章来源:https://blog.csdn.net/weixin_74113106/article/details/134897834
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!