什么时候一个空的类将变得不空?答案是当 C++ 得到了它。假如你自己不声明一个拷贝构造函数,一个拷贝赋值运算符和一个析构函数,编译器就会为这些东西声明一个它自己的版本。而且,假如你自己连一个构造函数都没有声明,编译器就会为你声明一个缺省构造函数。所有这些函数都被声明为 public 和 inline(参见 Item 30)。作为结果,假如你写
class NamedObject { public: // this ctor no longer takes a const name, because nameValue // is now a reference-to-non-const string. The char* constructor // is gone, because we must have a string to refer to.
NamedObject(std::string& name, const T& value); ... // as above, assume no // operator= is declared private: std::string& nameValue; // this is now a reference const T objectValue; // this is now const }; 现在,考虑这里会发生什么:
NamedObject<int> p(newDog, 2); // when I originally wrote this, our // dog Persephone was about to // have her second birthday NamedObject<int> s(oldDog, 36); // the family dog Satch (from my // childhood) would be 36 if she // were still alive
p = s; // what should happen to // the data members in p? 赋值之前,p.nameValue 和 s.nameValue 都引向 string 对象,但并非同一个。那个赋值对 p.nameValue 产生了什么影响呢?赋值之后,p.nameValue 所引向的字符串是否就是 s.nameValue 所引向的那一个呢,也就是说,引用本身被改变了?假如是这样,就违反了常规,因为 C++ 并没有提供使一个引用引向另一个对象的方法。换一种思路,是不是 p.nameValue 所引向的那个 string 对象被改变了,从而保持指针或引用还是指向那个对象,也就是说,赋值并没有直接影响对象?这是编译器产生的拷贝赋值运算符应该做的事情吗?