码迷,mamicode.com
首页 > 其他好文 > 详细

EC读书笔记系列之3:条款5、条款6、条款7

时间:2015-10-27 23:56:21      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

条款5:了解C++默默编写并调用哪些函数

记住:

★编译器可以(仅仅是可以,并非必须,仅当程序中有这样的用法时才会这么做!!!)暗自为class创建default构造函数,copy构造函数,copy assignment操作符以及析构函数。

 --------------------------------------------------------------------------------------------------------------------------------------------

  当你写一个空类,编译器会为其声明(仅仅是声明!!!)default构造函数,copy构造函数,copy assignment操作符和析构函数,它们都是public且inline。唯有当这些函数被需要(被调用),它们才会被编译器真正创建出来。

   

  对于copy constructor和copy assignment操作符,编译器创建的版本只是单纯地将来源对象的每个non-static成员变量拷到目标对象。

 

特殊情形:

    对于内含reference或者const成员的class,编译器会拒绝为其生成copy assignment操作符。若你打算这种类支持assignment操作,就必须自己定义copy assignment操作符。还有一种情况:若某个bases classes将copy assignment操作符声明为private,编译器将拒绝为其derived classes生成一个copy assignment操作符。毕竟编译器为derived classes所生的copy assignment操作符想象中可以处理base class成分,但它们当然无法调用derived class无权调用的成员函数。

 

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

记住:

★为驳回编译器自动(暗自)提供的功能,可将相应的成员函数声明为private并且不予实现。使用像Uncopyable(下面会讲)这样的base class也是一种做法。

 --------------------------------------------------------------------------------------

  借由声明一个成员函数,可阻止编译器暗自创建其专属版本(注意所有编译器产出的函数都是public);而令这些函数为private,可以阻止人们调用。但即使这样,member functions和friend函数还是可以调用你的private函数,解决方法是,仅声明这个private函数而不去定义,这样在不慎调用时会发生连接错误。(C++ iostream程序库中阻止copying行为就是这么做的!!!)

 

  另一种方法所谓的可将连接期错误移至编译期(好事,毕竟越早侦测出错误越好):

class Uncopyable { //Uncopyable的使用颇为微妙!!!

    protected:
        Uncopyable() {}
        ~Uncopyable() {}
    
    private:
        Uncopyable( const Uncopyable & );
        Uncopyable& operator=( const Uncopyable& );
};

class HomeForSale : private Uncopyable {
    //这样这个class就不用再声明私有的copy构造函数和
    //copy assignment操作符
};

  这样的话,只要任何人--甚至是member函数或friend函数--尝试拷贝HomeForSale 对象,编译器便试着生成一个copy构造函数和一个copy assignment操作符,而且这些函数的“编译器生成版”会尝试调用其base class的对应兄弟,而那些调用会被编译器拒绝(这就将本在在连接期的错误移到了编译期!!!),∵其base class的拷贝函数是private。不过这样做的一个问题是:使用这项技术可能导致多重继