条款14确定基类有虚析构函数

条款14确定基类有虚析构函数

ID:30173204

大小:59.07 KB

页数:6页

时间:2018-12-27

条款14确定基类有虚析构函数_第1页
条款14确定基类有虚析构函数_第2页
条款14确定基类有虚析构函数_第3页
条款14确定基类有虚析构函数_第4页
条款14确定基类有虚析构函数_第5页
资源描述:

《条款14确定基类有虚析构函数》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、条款14:确定基类有虚析构函数虚析构函数是为了解决这样的一个问题:基类的指针指向派生类对象,并用基类的指针删除派生类对象。  有时,一个类想跟踪它有多少个对象存在。一个简单的方法是创建一个静态类成员来统计对象的个数。这个成员被初始化为0,在构造函数里加1,析构函数里减1。(条款m26里说明了如何把这种方法封装起来以便很容易地添加到任何类中,“myarticleoncountingobjects”提供了对这个技术的另外一些改进)设想在一个军事应用程序里,有一个表示敌人目标的类:classenemytarget{public:e

2、nemytarget(){++numtargets;}enemytarget(constenemytarget&){++numtargets;}~enemytarget(){--numtargets;}staticsize_tnumberoftargets(){returnnumtargets;}virtualbooldestroy();//摧毁enemytarget对象后//返回成功private:staticsize_tnumtargets;//对象计数器};//类的静态成员要在类外定义;//缺省初始化为0size_te

3、nemytarget::numtargets;这个类不会为你赢得一份政府防御合同,它离国防部的要求相差太远了,但它足以满足我们这儿说明问题的需要。敌人的坦克是一种特殊的敌人目标,所以会很自然地想到将它抽象为一个以公有继承方式从enemytarget派生出来的类(参见条款35及m33)。因为不但要关心敌人目标的总数,也要关心敌人坦克的总数,所以和基类一样,在派生类里也采用了上面提到的同样的技巧:classenemytank:publicenemytarget{public:enemytank(){++numtanks;}ene

4、mytank(constenemytank&rhs):enemytarget(rhs){++numtanks;}~enemytank(){--numtanks;}staticsize_tnumberoftanks(){returnnumtanks;}virtualbooldestroy();private:staticsize_tnumtanks;//坦克对象计数器};(写完以上两个类的代码后,你就更能够理解条款m26对这个问题的通用解决方案了。)最后,假设程序的其他某处用new动态创建了一个enemytank对象,然后用d

5、elete删除掉:enemytarget*targetptr=newenemytank;...deletetargetptr;到此为止所做的一切好象都很正常:两个类在析构函数里都对构造函数所做的操作进行了清除;应用程序也显然没有错误,用new生成的对象在最后也用delete删除了。然而这里却有很大的问题。程序的行为是不可预测的——无法知道将会发生什么。c++语言标准关于这个问题的阐述非常清楚:当通过基类的指针去删除派生类的对象,而基类又没有虚析构函数时,结果将是不可确定的。这意味着编译器生成的代码将会做任何它喜欢的事:重新格

6、式化你的硬盘,给你的老板发电子邮件,把你的程序源代码传真给你的对手,无论什么事都可能发生。(实际运行时经常发生的是,派生类的析构函数永远不会被调用。在本例中,这意味着当targetptr删除时,enemytank的数量值不会改变,那么,敌人坦克的数量就是错的,这对需要高度依赖精确信息的部队来说,会造成什么后果?)为了避免这个问题,只需要使enemytarget的析构函数为virtual。声明析构函数为虚就会带来你所希望的运行良好的行为:对象内存释放时,enemytank和enemytarget的析构函数都会被调用。和绝大部分

7、基类一样,现在enemytarget类包含一个虚函数。虚函数的目的是让派生类去定制自己的行为(见条款36),所以几乎所有的基类都包含虚函数。如果某个类不包含虚函数,那一般是表示它将不作为一个基类来使用。当一个类不准备作为基类使用时,使析构函数为虚一般是个坏主意。请看下面的例子,这个例子基于arm(“theannotatedc++referencemanual”)一书的一个专题讨论。//一个表示2d点的类classpoint{public:point(shortintxcoord,shortintycoord);~point(

8、);private:shortintx,y;};如果一个shortint占16位,一个point对象将刚好适合放进一个32位的寄存器中。另外,一个point对象可以作为一个32位的数据传给用c或fortran等其他语言写的函数中。但如果point的析构函数为虚,情况就会改变。实现虚函数需要

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。