■本文内容■
□第一节 <引言>
在条款五的讲解中,我们已经知道编译器是聪明的家伙,它会帮助你生成类的构造函数、析构函数、一个copy构造函数和一个赋值运算符。
有时真的要感谢编译器所做的这一切,因为我们确实需要如此。但有的时候这一切又会给我们带来麻烦,本条款的介绍主题是麻烦的产生及如何解决。

□第二节 <案例:人员管理系统>
在一个人员管理系统中,有个class来描述每个人的信息是再合理不过的。
class PersonInfo{...};
那么下面的声明是合理的。
PersonInfo hanHan;
PersonInfo fangZhouZi;
那么下面的赋值也是合理的。
Person biaoGe(hanHan); // 用韩寒的信息拷贝出表哥--合理吗
hanHan = fangZhouZi; // 让韩寒成为方舟子--合理吗
显然,在现实中这些都是不合理的:要不违反伦理(克隆),要不目前的科技尚不能实现。对于编译器来说这没有什么不妥的地方。
所以我们要做的就是要让这逆天的情况永远不要发生。

□第三节 <寻找真凶>
好吧,也许写PersonInfo类的程序猿的本意并不是如此,但事实发生了就要找到真凶。其实,真凶也不难找到,就是那个自作聪明的编译器。
因为程序猿并没有声明Copy构造函数和Copy操作符。因为条款五中已经指出,如果你声明它们,而某些人尝试调用它们,编译器就会声明。

□第四节 <阻止犯罪>
如果在现实中,犯这么严重的罪,编译器肯定被抓去劳动改造了。既然不能给编译器判刑,那就要想个办法,防止它继续犯罪。
程序猿经过三天两夜的苦思冥想终于想到了一个自认为很好的方法。因为由编译器产生的函数都是public的,所以只要我自行定义它们,并且
以private修饰,那么编译器就不会生成它们了。但后来这个方法并不是绝对安全,因为成员函数和友元函数还是可以调用private函数的。
程序猿灵机一动:可以不实现这些函数啊。于是就有了下面的代码。

class PersonInfo {
public:
...
private:
PersonInfo(const PersonInfo&);
PersonInfo& operator=(const PersonInfo&);
};

再来看一下代码。private修饰符限定了只有成员函数和友元函数调用Copy函数和赋值运算符;而当真正调用的时候,由于未定义,连接器会报错。

程序猿是个好学生,他觉得错误可以在编译的阶段就被发现。事实上还真的被他找到了。于是他又写出了下面的代码。

class UnCopyable {
protected:
UnCopyable() {}
~UnCopyable() {}
private:
UnCopyable(const UnCopyable&);
UnCopyable& operator=(const UnCopyable&);
};
class PersonInfo : private UnCopyable {
...
};

再来看一下代码。只要任何人拷贝PersonInfo对象,编译器就会试着生成一个Copy构造函数和一个Copy操作符。
在尝试调用UnCopyable的对应的兄弟,很显然会被编译器毫不留情的拒绝:因为它们是private类型的。

到此,事情有了完美的结局,程序猿完美的避免了逆天的事再发生,编译器还是像以前一样尽职尽责。

■总结■
如果不需要编译器献的殷勤,就明确的拒绝它。拒绝的方式是可将相应的成员函数声明为private,并且不予实现。
或者像UnCopyable这样类也是一种做法,虽然会产生多重继承的问题。
目前该条准则在GUI项目中并没有发现有使用的地方。
(注:文中所用的人名、称呼等均不带有任何感情色彩,请勿对号入座!)

[Effective C++ --006]若不能使用编译器自动生成的函数,就该明确拒绝的更多相关文章

  1. 【Effective c++】条款6:若不想使用编译器自动生成的函数就应该明确拒绝

    地产中介卖的是房子,其使用的中介软件系统应该有个类用来描述卖掉的房子 class HomeFoeSale { ......} 但是任何房子都是独一无二的,不应该存在两个房子拥有同样的属性,因此以下操作 ...

  2. Effective C++ 之 Item 6 : 若不想使用编译器自动生成的函数,就该明确拒绝

    Effective C++ chapter 2. 构造 / 析构 / 赋值运算 (Constructors, Destructors, and Assignment Operators) Item 6 ...

  3. Effective C++ -----条款06:若不想使用编译器自动生成的函数,就该明确拒绝

    为驳回编译器自动提供的功能,可将相应的成员函数声明为private并且不予实现. 使用像Uncopyable这样的base class也是一种做法(即先声明一个基类,然后私有继承它).这其实有点像使用 ...

  4. Effective C++学习笔记 条款06:如不想使用编译器自动生成的函数,就该明确拒绝

    一.为驳回编译器自动提供的机能,可将相应成员函数声明为private并且不予实现.(如果你仅仅是自己不实现的话,编译器会帮你实现) 如: class A { public: A(const strin ...

  5. Effective C++_笔记_条款06_若不想使用编译器自动生成的函数,就该明确拒绝

    (整理自Effctive C++,转载请注明.整理者:华科小涛@http://www.cnblogs.com/hust-ghtao/) 通常如果你不希望class支持某一特定机能,只要不声明对应函数就 ...

  6. 读书笔记 effective c++ Item 6 如果你不想使用编译器自动生成的函数,你需要明确拒绝

    问题描述-阻止对象的拷贝 现实生活中的房产中介卖房子,一个服务于这个中介的软件系统很自然的会有一个表示要被销售的房屋的类: class HomeForSale { ... }; 每个房产中介会立刻指出 ...

  7. Effective C++ 条款06:若不想使用编译器自动生成的函数,就该明确拒绝

    规则一 将成员函数声明为private而且故意不实现他们 class HomeForSale { public: ... private: ... HomeForSale(const HomeForS ...

  8. Effective C++ 条款六 若不想使用编译器自动生成的函数,就该明确拒绝

    class HomeForSale //防止别人拷贝方法一:将相应的成员函数声明为private并且不予实现 { public: private: HomeForSale(const HomeForS ...

  9. C++如何拒绝编译器自动生成的函数

    每一个class,编译器都会自动生成四个特殊成员函数: destructor(析构函数) default constructor(默认构造函数) copy constructor(copy构造函数) ...

随机推荐

  1. 思考之spring的ioc

    控制反转 英语:Inversion of control,缩写为IoC 我想很多同学都会思考过这样的一个问题,控制反转,什么地方反转了,是不是翻译的不对? 这里插一句 当年马云借着盖茨的嘴说:“互联网 ...

  2. 在ubuntu on windows 上安装jekyll

    已知问题 安装ruby之后,重新启动ubuntu on windows,输入ruby命令,提示找不到. 发现的解决办法 执行下面命令 source /home/xxxx/.rvm/scripts/rv ...

  3. C# 中 string.Empty、""、null的区别

    原文C# 中 string.Empty."".null的区别 一.string.Empty 和 "" 1.Empty是string类中的一个静态的只读字段,它是 ...

  4. Print the numbers between 30 to 3000.

    Microsoft Interview Question Developer Program Engineers 看到一个题目比较有意思: Print the numbers between 30 t ...

  5. Zabbix探索:LDAP的认证方式

    这两天部署了Zabbix测试环境,终于用Puppet部署完成了.总是存在一些小问题,如服务不起动啦之类的. LDAP验证方式配置 刚刚配置Zabbix的用户管理,使用LDAP方式认证. 比较惊喜的是L ...

  6. openCV 直方图统计

    直方图显示 #include <opencv2/opencv.hpp> using namespace std; using namespace cv; int main(int argc ...

  7. html中a标签中的onclick和href的使用

    1. 链接的 onclick 事件被先执行,其次是 href 属性下的动作(页面跳转,或 javascript 伪链接): 假设链接中同时存在 href 与 onclick,如果想让 href 属性下 ...

  8. uva 11275 3D Triangles

    题意:三维空间中,给出两个三角形的左边,问是否相交. 面积法判断点在三角形内: #include<cstdio> #include<cmath> #include<cst ...

  9. PetShop学习第四天

    ASP.NET缓存 1.页输出缓存分为整页缓存和部分页缓存.我们可以通过@OutputCache指令来完成对Web页面的输出缓存.

  10. hdu4612-Warm up(边的双连通分量)

    题意:有n个点,m条边,有重边.现在可以任意在图上添加一条边,求桥的最少数目. 题解:思路就是求出双连通分量之后缩点成为一棵树,然后求出树的直径,连接树的直径就能减少最多的桥. 难点在于:有!重!边! ...