C 箴言:了解C 偷偷加上和调用了什么

2008-02-23 05:40:45来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

  几乎每一个您自己写的类都会有一个或多个构造函数,一个析构函数和一个拷贝赋值运算符。不要惊奇,那是些就像您的面包黄油相同的函数,他们控制着基本的操作,如创建一个新的对象并确保已被初始化,消除一个函数并确保他被完全清除,连同为对象赋予一个新值。这些函数中出现错误,将引起您的类出现影响深远的,而且令人不快的反弹,所以确保他们正确是生死攸关的事情。本章中,我将对如何组装这些函数以成为一个好的类的中枢骨干提供一些指导。

  什么时候一个空的类将变得不空?答案是当 C 得到了他。假如您自己不声明一个拷贝构造函数,一个拷贝赋值运算符和一个析构函数,编译器就会为这些东西声明一个他自己的版本。而且,假如您自己连一个构造函数都没有声明,编译器就会为您声明一个缺省构造函数。任何这些函数都被声明为 public 和 inline(参见 Item 30)。作为结果,假如您写

class Empty{};

  在本质上和您如下写是相同的:

class Empty {
 public:
  Empty() { ... } // default constructor
  Empty(const Empty& rhs) { ... } // copy constructor
  ~Empty() { ... } // destructor - see below
  // for whether it’s virtual
  Empty& operator=(const Empty& rhs) { ... } // copy assignment operator
};

  这些函数只有在他们被需要的时候才会生成,但是并无需做太多的事情,就会用到他们。下面的代码会促使每一个函数生成:

Empty e1; // default constructor;
// destructor

Empty e2(e1); // copy constructor

e2 = e1; // copy assignment operator

  假设编译器为您写成了这些函数,那么他们做些什么呢?缺省构造函数和析构函数主要是给编译器一个地方放置“幕后的”诸如调用基类和 non-static 数据成员的构造函数和析构函数的代码。注意,生成的析构函数是非虚拟(non-virtual)的,除非他从一个基类继承而来,而基类声明了一个虚析构函数(这种情况下,函数的虚拟性来自基类)。

  编译器版本的拷贝构造函数和拷贝赋值运算符,只是简单地从原对象拷贝每一个 non-static 数据成员到目标对象。例如,考虑一个将名字和类型为 T 的对象联系起来的 NamedObject 模板:

template<typename T>
class NamedObject {
 public:
  NamedObject(const char *name, const T& value);
  NamedObject(const std::string& name, const T& value);
  ..
 private:
  std::string nameValue;
  T objectValue;
};

  因为 NamedObject 中声明了构造函数,编译器就不会再生成缺省构造函数。这一点很重要,他意味着假如您足够谨慎地设计您的类,使他需要构造函数参数,您就不必顾虑编译器会不顾您的决定,轻率地增加一个无需参数的构造函数。

  NamedObject 既没有声明拷贝构造函数也没有声明拷贝赋值运算符,所以编译器将生成这些函数(当然是在需要的时候)。看,这就是拷贝构造函数的用法:

NamedObject<int> no1("Smallest Prime Number", 2);
NamedObject<int> no2(no1); // calls copy constructor

[1] [2] 下一页




标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇: C 箴言:拒绝不想用的编译器产生的函数

下一篇: C 箴言:视类设计为类型设计

热门词条
热门标签