Effective C++读书笔记---为多态基类声明为virtual析构函数
2016-08-05 16:48
330 查看
本篇文章有三个重点
1.为多态基类声明为virtual析构函数
原因很简单,在释放基类指针时会先调用继承类的析构函数。
只有当class内含至少一个virtual函数时,才能将其声明为virtual析构函数。无故声明virtual会增加内存开销。
对于纯虚析构函数,在声明为纯虚析构函数后还需要为其提供一份定义,因为析构函数的运作方式是最深层派生的class其析构函数最先被调用,然后是每一个基类的析构函数被调用。
2.别让异常逃离析构函数
在析构函数的异常行为容易导致内存泄漏等不明确行为,因此建议析构函数需要对可能的异常行为进行处理
原则上尽量不要讲有风险的行为放置到析构函数中,可以提供一个接口执行该操作。
3.绝不在构造和析构过程中调用virtual函数
此时如果构造一个BuyTransaction对象,首先调用基类的构造函数。
基类的在构造时,此时的对象类型是基类对象而非派生类对象,因此会直接调用基类的虚函数。
对于析构函数同样如此,在进入基类的析构函数后会对象会变为基类对象。
因此不要在构造和析构函数里调用virtual函数。
1.为多态基类声明为virtual析构函数
原因很简单,在释放基类指针时会先调用继承类的析构函数。
只有当class内含至少一个virtual函数时,才能将其声明为virtual析构函数。无故声明virtual会增加内存开销。
对于纯虚析构函数,在声明为纯虚析构函数后还需要为其提供一份定义,因为析构函数的运作方式是最深层派生的class其析构函数最先被调用,然后是每一个基类的析构函数被调用。
2.别让异常逃离析构函数
在析构函数的异常行为容易导致内存泄漏等不明确行为,因此建议析构函数需要对可能的异常行为进行处理
class DBConn{ public: ~DBConn() { try { db.close(); } catch(..) { } }; }
原则上尽量不要讲有风险的行为放置到析构函数中,可以提供一个接口执行该操作。
3.绝不在构造和析构过程中调用virtual函数
class Transaction { public: Transaction(); virtual void logTransaction() const = 0; }; Transaction::Transaction() { ... logTransaction(); //在构造函数中调用virtual函数 } void BuyTransaction::public Transaction { public: virtual void logTransaction() const; }
此时如果构造一个BuyTransaction对象,首先调用基类的构造函数。
基类的在构造时,此时的对象类型是基类对象而非派生类对象,因此会直接调用基类的虚函数。
对于析构函数同样如此,在进入基类的析构函数后会对象会变为基类对象。
因此不要在构造和析构函数里调用virtual函数。
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- c#中虚函数的相关使用方法
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- C++联合体转换成C#结构的实现方法
- C++高级程序员成长之路
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- 使用Lua来扩展C++程序的方法
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C++的template模板中class与typename关键字的区别分析