确定基类有虚析构函数

有时,一个类想跟踪它有多少个对象存在。一个简单的方法是创建一个静态类成员来统计对象的个数。这个成员被初始化

为0,在构造函数里加1,析构函数里减1。(条款m26里说明了如何把这种方法封装起来以便很容易地添加到任何类中,

“my article on counting objects”提供了对这个技术的另外一些改进)

设想在一个军事应用程序里,有一个表示敌人目标的类:
确定基类有虚析构函数确定基类有虚析构函数代码classenemytarget {

public:

enemytarget() {
++numtargets; }

enemytarget(
constenemytarget&) {++numtargets; }

~enemytarget() {--numtargets; }

staticsize_t numberoftargets()

{
returnnumtargets; }

virtualbooldestroy();//摧毁enemytarget对象后

//返回成功

private:

staticsize_t numtargets;//对象计数器

};

// 类的静态成员要在类外定义;

// 缺省初始化为0

size_t enemytarget::numtargets;

这个类不会为你赢得一份政府防御合同,它离国防部的要求相差太远了,但它足以满足我们这儿说明问题的需要。

敌人的坦克是一种特殊的敌人目标,所以会很自然地想到将它抽象为一个以公有继承方式从enemytarget派生出来的类(参

见条款35及m33)。因为不但要关心敌人目标的总数,也要关心敌人坦克的总数,所以和基类一样,在派生类里也采用了上

面提到的同样的技巧:
确定基类有虚析构函数确定基类有虚析构函数代码classenemytank:publicenemytarget {

public:

enemytank() {
++numtanks; }

enemytank(
constenemytank&rhs)

: enemytarget(rhs)

{
++numtanks; }

~enemytank() {--numtanks; }

staticsize_t numberoftanks()

{
returnnumtanks; }

virtualbooldestroy();

private:

staticsize_t numtanks;//坦克对象计数器

};

(写完以上两个类的代码后,你就更能够理解条款m26对这个问题的通用解决方案了。)

最后,假设程序的其他某处用new动态创建了一个enemytank对象,然后用delete删除掉:

enemytarget *targetptr = new enemytank;

...

delete targetptr;

到此为止所做的一切好象都很正常:两个类在析构函数里都对构造函数所做的操作进行了清除;应用程序也显然没有错

误,用new生成的对象在最后也用delete删除了。然而这里却有很大的问题。程序的行为是不可预测的——无法知道将会发

生什么。

c++语言标准关于这个问题的阐述非常清楚:当通过基类的指针去删除派生类的对象,而基类又没有虚析构函数时,结果将

是不可确定的。这意味着编译器生成的代码将会做任何它喜欢的事:重新格式化你的硬盘,给你的老板发电子邮件,把你

的程序源代码传真给你的对手,无论什么事都可能发生。(实际运行时经常发生的是,派生类的析构函数永远不会被调

用。在本例中,这意味着当targetptr 删除时,enemytank的数量值不会改变,那么,敌人坦克的数量就是错的,这对需要高

度依赖精确信息的部队来说,会造成什么后果?)

为了避免这个问题,只需要使enemytarget的析构函数为virtual。声明析构函数为虚就会带来你所希望的运行良好的行为:对

象内存释放时,enemytank和enemytarget的析构函数都会被调用。

和绝大部分基类一样,现在enemytarget类包含一个虚函数。虚函数的目的是让派生类去定制自己的行为(见条款36),所

以几乎所有的基类都包含虚函数。
原文链接: https://www.cnblogs.com/lancidie/archive/2010/10/20/1856730.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/16349

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午4:38
下一篇 2023年2月7日 下午4:38

相关推荐