■本文内容■
□第一节 <引言>
在条款五的讲解中,我们已经知道编译器是聪明的家伙,它会帮助你生成类的构造函数、析构函数、一个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. 关闭 VS的实时调试器

    可以这样关闭: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger HKEY_LOCAL_ ...

  2. Session简介

    摘要:虽然session机制在web应用程序中被采用已经很长时间了,但是仍然有很多人不清楚session机制的本质,以至不能正确的应用这一技术.本文将详细讨论session的工作机制并且对在Java ...

  3. 【Java基础之容器】Iterator

    Iterator: ->所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象 ->Iterator对象称作迭代器,用以方便的实 ...

  4. android listview 使用checkbox问题

    在android中使用listview时需要了解listview加载数据的原理,为了避免listview由于列表项过多每次需要进行new造成性能低下的问题,android中的listview使用了控件 ...

  5. Ext入门学习系列(四)面板控件

    第四章 使用面板 上节学习了Ext复杂对话框,更进一步了解了Ext的运行机制.本章重点来了解Ext所有控件的基础——面板控件. 一.Ext的面板是什么? 同样先来看看几个效果: 基本面板,点击右上角小 ...

  6. [Bhatia.Matrix Analysis.Solutions to Exercises and Problems]ExI.3.6

    If $A$ is a contraction, show that $$\bex A^*(I-AA^*)^{1/2}=(I-A^*A)^{1/2}A^*. \eex$$ Use this to sh ...

  7. CentOS安装nvidia显卡驱动

    1.下载 nvidia 相应的驱动: 2.修改/etc/modprobe.d/blacklist.conf文件,在里面加入blacklist nouveau. 3.重建image $ mv /boot ...

  8. HW5.33

    import java.util.Calendar; public class Solution { public static void main(String[] args) { long tot ...

  9. Linux下用hostapd架无线AP

    Published by 荒野无灯 on 2011-10-08 00:56:02 under 服务器/MySQL Tags: 路由,无线AP,hostapd 34452 views 本文将介绍在lin ...

  10. delphi 调用 webservice (.NET C#版)

    uses XMLIntf, XMLDoc; XML to XTR文件转换 .File-->open打开你要分析的XML文件 .在左边选择你要分析的接点,双击加到中间的转换列表中 .Create- ...