c++箴言:多态基类中将析构函数声明为虚拟

c++箴言:多态基类中将析构函数声明为虚拟

ID:1198699

大小:39.00 KB

页数:4页

时间:2017-11-08

c++箴言:多态基类中将析构函数声明为虚拟_第1页
c++箴言:多态基类中将析构函数声明为虚拟_第2页
c++箴言:多态基类中将析构函数声明为虚拟_第3页
c++箴言:多态基类中将析构函数声明为虚拟_第4页
资源描述:

《c++箴言:多态基类中将析构函数声明为虚拟》由会员上传分享,免费在线阅读,更多相关内容在应用文档-天天文库

1、C++箴言:多态基类中将析构函数声明为虚拟  有很多方法可以跟踪时间的轨迹,所以有必要建立一个TimeKeeper基类,并为不同的计时方法建立派生类:  classTimeKeeper{ public:  TimeKeeper();  ~TimeKeeper(); ...};classAtomicClock:publicTimeKeeper{...};classWaterClock:publicTimeKeeper{...};classWristWatch:publicTimeKeeper{...};  很多客户只是想简单地取得时间而不

2、关心如何计算的细节,所以一个factory函数——返回一个指向新建派生类对象的基类指针的函数——被用来返回一个指向计时对象的指针: TimeKeeper*getTimeKeeper();//returnsapointertoadynamic-//allyallocatedobjectofaclass//derivedfromTimeKeeper按照factory函数的惯例,getTimeKeeper返回的对象是建立在堆上的,所以为了避免泄漏内存和其他资源,最重要的就是要让每一个返回的对象都可以被完全删除。 TimeKeeper*ptk=

3、getTimeKeeper();//getdynamicallyallocatedobject//fromTimeKeeperhierarchy...//useitdeleteptk;//releaseittoavoidresourceleak现在我们精力集中于上面的代码中一个更基本的缺陷:即使客户做对了每一件事,也无法预知程序将如何运转。  问题在于getTimeKeeper返回一个指向派生类对象的指针(比如AtomicClock),那个对象通过一个基类指针(也就是一个TimeKeeper*指针)被删除,而且这个基类(TimeKeep

4、er)有一个非虚的析构函数。祸端就在这里,因为C++指出:当一个派生类对象通过使用一个基类指针删除,而这个基类有一个非虚的析构函数,则结果是未定义的。运行时比较有代表性的后果是对象的派生部分不会被销毁。如果getTimeKeeper返回一个指向AtomicClock对象的指针,则对象的AtomicClock部分(也就是在AtomicClock类中声明的数据成员)很可能不会被销毁,AtomicClock的析构函数也不会运行。然而,基类部分(也就是TimeKeeper部分)很可能已被销毁,这就导致了一个古怪的“部分析构”对象。这是一个泄漏资

5、源,破坏数据结构以及消耗大量调试时间的绝妙方法。排除这个问题非常简单:给基类一个虚析构函数。于是,删除一个派生类对象的时候就有了你所期望的正确行为。将销毁整个对象,包括全部的派生类部分: classTimeKeeper{ public:  TimeKeeper();  virtual~TimeKeeper();  ...};TimeKeeper*ptk=getTimeKeeper();...deleteptk;//nowbehavescorrectly  类似TimeKeeper的基类一般都包含除了析构函数以外的其它虚函数,因为虚函数的

6、目的就是允许派生类定制实现(参见Item34)。例如,TimeKeeper可能有一个虚函数getCurrentTime,在各种不同的派生类中有不同的实现。几乎所有拥有虚函数的类差不多都应该有虚析构函数。   如果一个类不包含虚函数,这经常预示不打算将它作为基类使用。当一个类不打算作为基类时,将析构函数声明为虚拟通常是个坏主意。考虑一个表现二维空间中的点的类: classPoint{//a2Dpoint public:  Point(intxCoord,intyCoord);  ~Point(); private:  intx,y;}; 

7、 如果一个int占32位,一个Point对象正好适用于64位的寄存器。而且,这样一个Point对象可以被作为一个64位的量传递给其它语言写的函数,比如C或者FORTRAN.如果Point的析构函数是虚拟的,情况就完全不一样了。   虚函数的实现要求对象携带额外的信息,这些信息用于在运行时确定该对象应该调用哪一个虚函数。典型情况下,这一信息具有一种被称为vptr(virtualtablepointer,虚函数表指针)的指针的形式。vptr指向一个被称为vtbl(virtualtable,虚函数表)的函数指针数组,每一个包含虚函数的类都关联

8、到vtbl.当一个对象调用了虚函数,实际的被调用函数通过下面的步骤确定:找到对象的vptr指向的vtbl,然后在vtbl中寻找合适的函数指针。   虚函数如何被实现的细节是不重要的。重要的是如果Point类

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

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

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