首页 > 代码库 > 条款45: 弄清C++在幕后为你所写、所调用的函数

条款45: 弄清C++在幕后为你所写、所调用的函数

当C++编译器通过它的时候。如果你没有声明下列函数,体贴的编译器会声明它自己的版本。这些函数是:一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符。另外,如果你没有声明任何构造函数,它也将为你声明一个缺省构造函数。所有这些函数都是公有的。换句话说,如果你这么写:

class Empty{};

和你这么写是一样的:

class Empty {public:  Empty();                        // 缺省构造函数  Empty(const Empty& rhs);        // 拷贝构造函数  ~Empty();                       // 析构函数 ---- 是否                                  // 为虚函数看下文说明  Empty&  operator=(const Empty& rhs);    // 赋值运算符  Empty* operator&();             // 取址运算符  const Empty* operator&() const;};

假设编译器为你写了函数,这些函数又做些什么呢?是这样的,缺省构造函数和析构函数实际上什么也不做,它们只是让你能够创建和销毁类的对象。注意,生成的析构函数一般是非虚拟的(参见条款14),除非它所在的类是从一个声明了虚析构函数的基类继承而来。缺省取址运算符只是返回对象的地址。这些函数实际上就如同下面所定义的那样:

inline Empty::Empty() {}inline Empty::~Empty() {}inline Empty * Empty::operator&() { return this; }inline const Empty * Empty::operator&() const{ return this; }

至于拷贝构造函数和赋值运算符,官方的规则是:缺省拷贝构造函数(赋值运算符)对类的非静态数据成员进行 "以成员为单位的" 逐一拷贝构造(赋值)。即,如果m是类C中类型为T的非静态数据成员,并且C没有声明拷贝构造函数(赋值运算符),m将会通过类型T的拷贝构造函数(赋值运算符)被拷贝构造(赋值)---- 如果T有拷贝构造函数(赋值运算符)的话。如果没有,规则递归应用到m的数据成员,直至找到一个拷贝构造函数(赋值运算符)或固定类型(例如,int,double,指针,等)为止。默认情况下,固定类型的对象拷贝构造(赋值)时是从源对象到目标对象的 "逐位" 拷贝。对于从别的类继承而来的类来说,这条规则适用于继承层次结构中的每一层,所以,用户自定义的构造函数和赋值运算符无论在哪一层被声明,都会被调用。

class NamedObject{public:    NamedObject(string &name, const int &value)        :nameValue(name), objectValue(value){}private:    string &nameValue;    const int objectValue;};void main(){    string newDog("persephone");    string oldDog("satch");    NamedObject p(newDog, 2);    NamedObject s(oldDog, 29);    p = s;}

 

条款45: 弄清C++在幕后为你所写、所调用的函数