Item 07 : 为多态基类声明virtual析构函数

 #include <iostream>
using namespace std; class Base {
public:
Base() : bValue() {}
virtual ~Base() { cout << "Base destructor" << endl; }
// ~Base() { cout << "Base destructor" << endl; }
virtual void print() {
cout << "print : base" << endl;
}
private:
int bValue;
}; class Derived : public Base {
public:
Derived() : dValue() {}
~Derived() {
cout << "Derived destructor" << endl;
}
void print() {
cout << "print : derived" << endl;
}
private:
int dValue;
}; int main() {
Base* p = new Derived();
p->print();
delete p;
}

注意Line 7和8,当基类的析构函数用的是Line7, 即基类析构函数是virtual时,Line32处执行delete p时,相当于调用p所指的析构函数,由于p是一个指向派生类对象的基类指针,且基类中析构函数是virtual的,所以满足了多态的发生条件,即此处调用的是派生类的析构函数Line19。派生类在析构的时候会自动调用其基类的析构函数,所以就有了下图的结果。

假如基类的析构函数不再是virtual的 (即将Line7注释掉,换成Line8),这样在Line32处调用delete p时, p本身是个基类指针,但是所指向的又是一个派生类对象。此时如果p所调用的函数是virtual的,那么p就直接调用派生类中的同名函数,即上面所描述的那样;若p所调用的函数不是virtual的,那它就老老实实的调用基类的函数。

所以将基类的析构函数换成non-virtual之后(即注释掉Line7换成Line8之后),结果如下:

这样导致的结果就是p所指的派生类对象只有基类部分得到释放,派生类对象中独属于派生类的部分仍留在堆上,导致内存泄漏。

==========================================================================================================

 #include <iostream>
using namespace std; class Point {
public:
Point(int xCoord, int yCoord);
~Point();
private:
int x, y;
}; class Point2 {
public:
Point2(int xCoord, int yCoord);
virtual ~Point2();
private:
int x, y;
}; class Point3 {
public:
Point3(int xCoord, int yCoord) : x(xCoord), y(yCoord) {}
~Point3() {}
private:
int x, y;
}; int main() {
cout << sizeof(Point) << endl;
cout << sizeof(Point2) << endl;
Point* p;
Point3 obj(,);
return ;
}

这段代码想要表达两个问题:

1. 虚函数由于vptr,vtbl,会占用一些额外空间。Point和Point2的差别就在于析构函数是否是virtual,输出结果为8,12.

2. 我把Point3这个class放在这的目的是想说明,对于Point和Point2这样的,类内部的构造函数、析构函数只有声明没有定义(都直接以;结尾的),在其成员函数-没有定义的情况下不妨碍对它们求sizeof和定义指针(L31),但是它们不能定义对象(像L32那样)。

============================================================================================================

Item 29 : 为“异常安全” 而努力是值得的

经验:异常安全函数即使发生异常也不会泄漏资源或允许任何数据结构败坏。这样的函数区分为三种
可能的保证:
基本型-->发生异常,程序处于某个合法状态
强烈型-->发生异常,程序处于原先状态
不抛异常型-->承诺绝不抛出异常 class PrettyMenu {
public:
void changeBackground(istream& imgSrc);
private:
Mutex mutex; //由于这个class希望用于多线程环境,所以它有这个互斥器作为并发控制之用
Image* bgImage; //目前的背景图像
int imageChanges; //背景图像被改变的次数
}; void PrettyMenu::changeBackground(std::istream &imgSrc) {
lock(&mutex); //取得互斥器
delete bgImage; //摆脱旧的背景图像
++imageChanges; //修改图像变更次数
bgImage = new Image(imgSrc); //安装新的背景图像
unlock(&mutex); //释放互斥器
} 解析:
泄漏资源:new Image(imgSrc) 导致异常的话,互斥器就不会 unlock
数据败坏:new Image(imgSrc) 导致异常的话,bgImage指向一个已删除的对象,imageChanges 也已被累加

ref

Effective C++ Notes的更多相关文章

  1. 转:Effective c + + notes

    补充自己的. 转自:http://blog.csdn.net/ysu108/article/details/9853963#t0 Effective C++ 笔记 目录(?)[-] 第一章 从C转向C ...

  2. ToDo系列

    leetcode http://www.cnblogs.com/TenosDoIt/tag/leetcode/ http://tech-wonderland.net/category/algorith ...

  3. Effective Objective-C 2.0 Reading Notes

    1. Literal Syntax NSString *someString = @"Effective Objective-C 2.0"; NSNumber *someNumbe ...

  4. Effective Java Index

    Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...

  5. Notes on <Assembly Language step by step>

    By brant-ruan Yeah, I feel very happy When you want to give up, think why you have held on so long. ...

  6. Reading Notes of Acceptance Test Engineering Guide

    The Acceptance Test Engineering Guide will provide guidance for technology stakeholders (developers, ...

  7. A Java back-end engineer's study notes

    loveincode's notes 学习工作中的一些记录,收藏. 人气很高的链接库 计算机基础相关笔记 操作系统 , 编译原理 , 计算机网络 , 互联网协议... 常用数据结构与算法 Java 实 ...

  8. Notes of O_DIRECT flag

    What is O_DIRECT Starting with kernel 2.4, Linux allows an application to bypass the buffer cache wh ...

  9. 高性能服务器设计(Jeff Darcy's notes on high-performance server design

    高性能服务器设计(Jeff Darcy's notes on high-performance server design 我想通过这篇文章跟大家共享一下我多年来怎样开发“服务器”这类应用的一些想法和 ...

随机推荐

  1. Tomcat服务器安装配置

    1.到http://tomcat.apache.org/官网下载Tomcat的zip版本,这样直接解压就行了,不用安装.我下载是Tomcat6.0版本的zip文件,解压在D:\Java\apache- ...

  2. Javac词法分析

    参考:<深入分析Java Web>技术内幕 许令波 词法分析过程涉及到的主要类及相关的继承关系如下: 词法分析的接口为Lexer,默认实现类为Scanner,Scanner会逐个读取Jav ...

  3. 2-6 js基础-ajax

    1.var oAjax=new XmlHttpRequest()//创建一个ajax对象,兼容非ie6 var oAjax=new ActiveXObject('Microsoft.XMLHTTP') ...

  4. 深入理解java集合框架之---------Arraylist集合 -----添加方法

    Arraylist集合 -----添加方法 1.add(E e) 向集合中添加元素 /** * 检查数组容量是否够用 * @param minCapacity */ public void ensur ...

  5. Redis: under the hood---转载

    http://pauladamsmith.com/articles/redis-under-the-hood.html#redis-under-the-hood How does the Redis  ...

  6. Django models 的增删改查

    增 from app01.models import * #create方式一: Author.objects.create(name='Alvin') #create方式二: Author.obje ...

  7. 事务,约束,范式,视图,索引,pl/sql

    1.操作分类:  DML. DDL. DCL manipulation     definition   control 2.transction 事务 起始于DML,遇到 commit ,rollb ...

  8. mvc手把手教你写excel导入[mvc+三层,没用EF]

    实习狗的每天新知识日常 准备工作: 1.在项目中添加对NPOI的引用,NPOI下载地址:http://npoi.codeplex.com/releases/view/38113 2.NPOI学习系列教 ...

  9. Docker学习(二): 镜像的使用与构建

    特别声明: 博文主要是学习过程中的知识整理,以便之后的查阅回顾.部分内容来源于网络(如有摘录未标注请指出).内容如有差错,也欢迎指正! =============系列文章============= 1 ...

  10. 网站压力测试 工具webbench

    webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好用,安装使用也特别方便,并且非常小. 主要是 -t 参数用着比较爽,下面参考了张宴的文章 ...