《Effect C++》学习------条款07:为多态基类声明virtual析构函数
2016-08-16 12:40
239 查看
条款07:为多态基类声明virtual析构函数
有许多种做法可以记录时间,因此,设计一个TimeKeeper base class和一些
derived classes作为不同的计时方法,相当合情合理:
class TimeKeeper{ public: TimeKeeper(); ~TimeKeeper(); class AtomicClock: public TimeKeeper{...}; //原子钟 class WaterClock: public TimeKeeper{...}; //水钟 class WristWatch: public TimeKeeper{...}; //腕表 ... }
许多客户只想在程序中使用时间,不想操心如何实现细节,这是可以用工厂模式,设计一个factory函数,返回指向一个计时对象。Factory函数“返回一个base类指针”,指向新生成的derived class对象:
TimeKeeper* getTimeKeeper(); TimeKeeper* p = getTimeKeeper(); ... delete p;
如上所示,分配的指针进行完相关操作后delete很重要。
由于p是一个基类的指针,当进行析构时,会调用基类的析构函数,也就是说会把p所指对象的基类部分进行,但是p实际指向了一个派生类的对象,对于派生类的数据怎么办呢?此时会产生不明确行为,这是造成内存泄露的一个绝佳方式。
如果我们把基类的析构函数做成虚函数,则这个问题就可以解决了:
class TimeKeeper{ public : TimeKeeper(); virtual ~TimeKeeper(); .... }; class AtomicClock : public TimeKeeper{...}; class WaterClock : public TimeKeeper{...}; class WristClock : public TimeKeeper{...};
再次进行析构时,由于析构函数是一个虚函数,所以在析构时,会在运行期来决定调用哪个类的析构函数,此时,经判断是派生类的析构函数,所以会调用派生类的析构函数,此时,可以把ptk所指向的对象全部析构。
结论:任何class只要带有virtual函数都几乎确定应该也有一个virtual析构函数。
如果一个class不含virtual函数,通常表示它并不意图被用做一个base class,即使被当作基类,也不希望用基类的指针来指向一个派生类的对象。当class不企图被当作base class,令其析构函数为virtual,往往不是一个好主意。如下类:
class Point{ public : Point(int xCoord, int yCoord) : x(xCoord),y(yCoord){} ~Point(); private: int x, y; }
这样一个类的对象,会占用64个字节的内存,如果其析构函数是一个虚函数,则此类的对象,将会是96字节,这样,浪费了50%的空间。
所以许多人的心得是:只有当class内含至少一个virtual函数,才为它声明一个virtual析构函数。
对于继承任何析构函数不是virtual的类,如果通过指针使用多态机制,最后通过delete该指向derived类型的base类型指针销毁原derived对象,就会出现泄漏的问题。
所以,包括所有STL容器和任何有非虚析构函数的类,请不要继承它们!!(C++11里面有一个final关键字,可以禁止派生,这样就好许多了!以后定义有非虚析构函数的类,最好都加上final关键字!而且标记为final的类,编译器则根本不会生成虚表。这样的代码显然更有效率。所以新标准真好!!!)
小技巧:但你需要一个抽象类,但是你没有一个虚函数,这时根据“当你打算使用的多态的时候,base class一般应该有个virtual析构函数”,你可以使用纯虚析构函数!
注意:这时必须为这个纯虚析构函数提供一个定义(普通纯虚函数不用提供定义)。因为析构函数的运作机理是最深处的基类先被调用,然后是其后的每一个基类的析构函数被调用!
并非所有的基类都是为了多态,对于不打算使用多态的情况,基类不需要virtual析构函数。
请记住:
- [x] Polymorphic base class 应该声明一个virtual析构函数。如果class带有任何virtual函数,它就应该拥有一个virtual析构函数。
- [x] Class的设计目的如果不是作为base class 使用,或不是为了具备多态性,就不应该声明virtual析构函数。
相关文章推荐
- Effective C++学习7 条款07:为多态基类声明virtual析构函数
- Effective C++学习笔记 条款07:为多态基类声明virtual析构函数
- Effective C++学习笔记 条款07:为多态基类声明virtual析构函数
- 条款07:为多态基类声明virtual析构函数
- 《Effective C++》学习笔记条款07 为多态基类声明virtual析构函数
- effective C++ 读书笔记 条款07 为多态基类声明virtual析构函数
- 条款07:为多态基类声明virtual析构函数
- 读书笔记《Effective C++》条款07:为多态基类声明virtual析构函数
- effective c++条款07为多态基类声明为virtual析构函数
- Effective C++ -----条款07:为多态基类声明virtual析构函数
- Effective c++学习笔记——条款07:为多态基类声明virtual析构函数
- Effective c++学习笔记——条款07:为多态基类声明virtual析构函数
- 条款07:为多态基类声明virtual析构函数
- 条款07:为多态基类声明virtual析构函数
- effective c++ 条款07(为多态基类声明virtual析构函数)整理
- 条款07:为多态基类声明virtual析构函数(Declare destructors virtual in polymorphic base classes.)
- 条款07:为多态基类声明virtual析构函数
- Effective C++_笔记_条款07_为多态基类声明virtual析构函数
- 条款07:为多态基类声明virtual析构函数
- Effective C++条款07解读:为多态基类声明virtual析构函数 (某公司招聘面试试题)