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. MySQL 备份数据库

    一.数据备份 1.备份一个数据库 mysqldump基本语法: mysqldump -u username -p dbname table1 table2 ...-> BackupName.sq ...

  2. Linux 操作系统常用的三种流012

    Linux 操作系统常用的三种流: 0 标准输入流 1 标准输出流 2 标准错误流 通常在写脚本启动程序,写log时候,会出现如下写法: nohup commod > log.txt 2> ...

  3. file_get_contents 抓取网页乱码。

    iconv string iconv ( string $in_charset , string $out_charset , string $str ) mb_convert_encoding st ...

  4. [Mysql 查询语句]——查询指定记录

    #比较 等于; 大于; 小于; 小于或等于; 大于或等于; 不等于; 排除掉; #指定范围查询 BETWEEN IN ; ; #指定集合查询 IN ,); ,); 集合元素可以是字符串类型 selec ...

  5. shell命令跟踪

    Linux Shell提供了两种方式来跟踪Shell脚本中的命令,以帮助我们准确的定位程序中存在的问题.下面的代码为第一种方式,该方式会将Shell脚本中所有被执行的命令打印到终端,并在命令前加&qu ...

  6. WPF 小知识点001

    1.DataGrid 单选事件 <DataGrid MinHeight="150"                  AutoGenerateColumns="Fa ...

  7. VS设置护眼色

    打开vs2013 选项 环境...如图所示

  8. [javaSE] IO流(装饰设计模式)

    装饰设计模式:当想要对已有的对象进行功能增强时,可以自定义类将已有的对象传入,并提供加强功能,自定义的该类称为装饰类 典型的: Reader--FileReader --BufferedReader ...

  9. 阿里云服务器windows server流量不大的情况下,tomcat经常出现访问阻塞,手动ctrl+c或者点击右键又访问正常

    我被这个问题折磨了好几天,因为这两天要帮别人做推广,不能再出现这样的情况了,不然广告费就白烧了,所以特意查了一下资料,结果解决方案被我找出来了. 问题发生原因是因为打开编辑选项后,一不小心点到dos窗 ...

  10. centos 6无法上外网

    1.先配置/etc/sysconfig/network-scripts/ifcfg-eth0 配置完成后能ping通内网.网关,但是上不了外网 DEVICE=eth0 HWADDR=:0C::FF:: ...