//---------------------------15/03/26----------------------------

//#5    了解c++默默编写并调用哪些函数

{

/*

c++会默默帮你声明一个copy构造函数,一个copy assignment操作符重载,

一个析构函数,一个default构造函数。并且都是 public inline的

因此如果写下:

*/

class Empty{};

//就好像写下这样的代码:

class Empty

{

public:

Empty(){...}

Empty(const Empty& rhs) {...}

~Empty(){...}

Empty&operator=(const Empty& rhs){...}

};

//1:这些函数,只有被需求(被调用)时,才会被编译器创建出来

/**

2:copy构造函数和copy assignment操作符,编译器创建的版本只是单纯地

将来源对象的每一个non_static成员拷贝到目标对象中去

**/

//3:在copy的时候:如果成员变量有copy构造函数,编译器就调用其copy构造函数,

//如果没有copy构造函数,就会拷贝每一个bits
来完成初始化

/*

4:在什么情况下编译器拒绝帮忙定义一个copy assignment?

1>对象内包含一个reference变量,原因:reference自身不可以被再次指向另一个值

如果你想让这个reference的内容改变成目标对象的内容,那需要自行实现operator=操作

其实也就是深拷贝。

2>对象内包含一个const变量,原因:更改const变量的值时不合法的。

3>如果base classes将copy assignment操作符声明为private。原因:原本derived
classes

的copy assignment操作符是可以处理base class成分的,但是现在他们无法调用了。

编译器就两手一摊,无能为力了。

*/

}

//#6    若不想使用编译器自动生成的函数,就该明确拒绝

{

/*

当你想使你的对象不能被复制时(比如每个人的资产都是私有的,不该被复制给别人),

你有两个方法可以做到:                                                 */

//  1>自己声明一个private的copy构造函数以及copy assignment操作符。

class HomeForSale

{

public:

...

private:

...

HomeForSale(const HomeForSale&);

HomeForSale&operator=(const HomeForSale&);

};

// 这样就声明了这两个函数,要注意的是,不要去实现它,这样可以在别人

// 使用这两个函数时报错(编译器报错),当成员函数或friend函数使用时,会产生连接时报错

//  2>为了时报错提早(所有报错都由编译器产生),可以专门设计一个base类:

class Uncopyable

{

protected:

Uncopyable(){}

~Uncopyable(){}

private:

Uncopyable(const Uncopyable&);

Uncopyable&operator=(const Uncopyable&);

};

/*

这样只要想阻止copying行为,只需要继承Uncopyable类就可以了

这里会产生几个微妙的实现和运用

1>不一定需要使用public继承

2>Uncopyable的析构函数可以不是virtual的(这个类不是接口,只能算是一个属性)

3>Uncopyable中不含数据,符合一个empty base class optimization的资格

4>由于常常被继承,很可能造成多重继承。

*/

//总结:如果你的类常需要从多个基类继承,那最好自己声明两个copy函数,否则,不妨从

//Uncopyable那继承。

}

//#7    为多态基类声明virtual析构函数

{

/*

这一点,不必多说,只要了解c++多态,都知道要给多态基类声明一个virtual析构函数防治内存泄漏

这个条款中比较新鲜的东西有两个:

1:不要为一个非多态用途的类声明virtual析构函数。原因是:

1>这么做会使的对象占用内存变大,

尤其是对于一些小巧的类来说,本来可以直接放在一个寄存器中的,一声明vitual属性,

在32位系统中就变大了32bits,在64位系统中就变大了64bits。这个大小就是一个指针的大小,

这个指针就是vptr指针,指向虚函数表,里面存放着由函数指针
构成的数组。

2>由于vptr指针,这个对象将变得没有移植性。因为其他语言没有vptr这东西。

2:如果想使一个base class获得不能被实例化
的特性,而这个base calss中又没有

pure vitual函数(纯虚函数),可以把析构函数设置为pure vitual函数。值得注意的是

你还是要为这个析构函数提供一份定义。因为基类析构函数总是会在其派生类调用时被调用。

*/

}

//#8    别让异常逃离析构函数

{

// 如果析构函数可以吐出异常,会造成程序的结束执行或不明确行为,看下面的例子:

class Widget

{

public:

...

~Widget(){...}

};

void doSomething()

{

std::vector<Widget> v;

}

/*

当vector被销毁时,vector会依次调用其中的所有widget对象(假设有10个),如果析构允许

抛出异常的话,析构第一个的时候,抛出了异常,为了确保不会发生内存泄漏,必须继续析构其他

九个widget,如果第二个异常又被抛出,现在有两个同时作用的异常,在两个异常同时存在的情况下,

程序不是结束执行就是导致不明确行为。

*/

//如果析构函数必须执行一个动作,而该动作可能在失败时抛出异常,那么应该这么做

//给客户提供一个动作,让他自己去调用,并在析构函数中检查是否完成,并吞下异常或终止程序

class DBConn

{

public:

...

void close()

{

db.close();

closed =true;

}

~DBConn()

{

if(!closed)

{

try

{

db.close();

}catch (...)

{

//记下对close调用失败的log

//选择是否中止

}

}

}

private:

DBConnection db;

bool closed;

};

//这样可以给客户一个调用close的机会,如果他自己不处理,也没法抱怨设计这个类的我们了。

}

effective c++ 笔记 (5-8)的更多相关文章

  1. Effective Java笔记一 创建和销毁对象

    Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...

  2. [Effective JavaScript 笔记] 第4条:原始类型优于封闭对象

    js有5种原始值类型:布尔值.数字.字符串.null和undefined. 用typeof检测一下: typeof true; //"boolean" typeof 2; //&q ...

  3. [Effective JavaScript 笔记] 第5条:避免对混合类型使用==运算符

    “1.0e0”=={valueOf:function(){return true;}} 是值是多少? 这两个完全不同的值使用==运算符是相等的.为什么呢?请看<[Effective JavaSc ...

  4. [Effective JavaScript 笔记]第3章:使用函数--个人总结

    前言 这一章把平时会用到,但不会深究的知识点,分开细化地讲解了.里面很多内容在高3等基础内容里,也有很多讲到.但由于本身书籍的篇幅较大,很容易忽视对应的小知识点.这章里的许多小提示都很有帮助,特别是在 ...

  5. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码

    函数是一种将代码作为数据结构存储的便利方式,代码之后可以被执行.这使得富有表现力的高阶函数抽象如map和forEach成为可能.它也是js异步I/O方法的核心.与此同时,也可以将代码表示为字符串的形式 ...

  6. [Effective JavaScript 笔记]第28条:不要信赖函数对象的toString方法

    js函数有一个非凡的特性,即将其源代码重现为字符串的能力. (function(x){ return x+1 }).toString();//"function (x){ return x+ ...

  7. java effective 读书笔记

    java effective 读书笔记 []创建和销毁对象 静态工厂方法 就是“封装了底层 暴露出一个访问接口 ” 门面模式 多参数时 用构建器,就是用个内部类 再让内部类提供构造好的对象 枚举 si ...

  8. Effective STL 笔记 -- Item 6 ~ 7: Container and Object Pointer

    Effective STL 笔记 – Item 6 ~ 7: Container and Object Pointer 中间两次笔记被删掉了,简单补一下: Item 3 中提到如果将对象直接放入容器中 ...

  9. Item 5:那些被C++默默地声明和调用的函数 Effective C++笔记

    Item 5: Know what functions C++ silently writes and calls 在C++中,编译器会自己主动生成一些你没有显式定义的函数,它们包含:构造函数.析构函 ...

  10. effective c++ 笔记 (1-3)

    // //  effective c++.cpp //  笔记 // //  Created by fam on 15/3/23. // // //-------------------------- ...

随机推荐

  1. CSS| font property

    字體屬性 常用的CSS字体名称 宋体 SimSun 黑体 SimHei 微软雅黑 Microsoft YaHei 微软正黑体 Microsoft JhengHei 新宋体 NSimSun 新细明体 P ...

  2. 转:.NET 面试题汇总(一)

    目录 本次给大家介绍的是我收集以及自己个人保存一些.NET面试题 简介 1.C# 值类型和引用类型的区别 2.如何使得一个类型可以在foreach 语句中使用 3.sealed修饰的类有什么特点 4. ...

  3. 转:winform 打包自动安装数据库

    vs2005 打包,并自动安装SQL数据库.创建部署项目    1.   在“文件”菜单上指向“添加项目”,然后选择“新建项目”.    2.   在“添加新项目”对话框中,选择“项目类型”窗格中的“ ...

  4. November 17th, 2017 Week 46th Friday

    If you shut the door to all errors, truth will be shut out. 你如果拒绝面对错误,真相也会被挡在门外. Sometimes being a f ...

  5. java使用elasticsearch分组进行聚合查询(group by)-项目中实际应用

    java连接elasticsearch 进行聚合查询进行相应操作 一:对单个字段进行分组求和 1.表结构图片: 根据任务id分组,分别统计出每个任务id下有多少个文字标题 .SQL:select id ...

  6. css多行省略-webkit-box-orient打包编译后失效原因

    原css代码: .dialog-for-plan .dialog-table .type>p { display: -webkit-box; -webkit-box-orient: vertic ...

  7. bat替换文件的指定内容

    需求:替换文件my.ini中的1000 为10000,bat脚本如下: c:cd C:\Program Files\MySQL\MySQL Server 5.5copy my.ini my1126ba ...

  8. gatewayworker中使用tcp协议连接硬件设备获取数据报错解决办法!

    运行后过段时间报错, Warning: Error while sending STMT_PREPARE packet. PID=1776 in D:\phpStudy\WWW\api\mysql-m ...

  9. impala客户端连接

    想要使用plsql连接oracle一样,使用类似工具连接impala的方法:ClouderaImpalaODBC32.msi下载地址:http://www.cloudera.com/downloads ...

  10. XmlSpy / XSD以及验证

    很早以前看过一句话:“XML就象空气”,在企业应用开发中XML是一个重要的数据交换标准.而XSD则可以用来校验XML的数据格式是否正确. 一个典型的XSD文件如下: <?xml version= ...