有3种情况,可以将一个object的内容作为另外个object的初值:
1. 明确的拷贝:X c_x2; X c_x = c_x2;
2. 函数参数:void foo(X xx);
3. 函数返回值:X foo() { X xx; return xx;};
假如类的设计者定义了一个拷贝构造,比如:
X::X( const X &x);
Y::Y( const Y &y, int = 0);
那么在大部分情况下,当一个类对象以另一个同类实体作为初值时,上述的构造会被调用。
位逐次拷贝:
1: //...
2: Word noun("book");
3:
4: void foo()
5: {
6: Word verb = noun;
7: }
很明显,verb是根据noun来进行初始化。但如果没见过Word的声明,无法确定是否显式的声明了拷贝构造?如果没有声明,那么是否编译器会自动合成实体调用呢?
1: //声明方式1:语意拷贝
2: class Word
3: {
4: public:
5: Word(const char*);
6: ~Word(){delete []str;};
7: private:
8: int cnt;
9: char *str;
10: }
在这样的拷贝声明下,当Word verb = noun时,verb和noun的str指针都指向相同的字符串“book”。因为Word(const char*)时,拷贝的并不是一个字符串内容,而是一个指向字符串“book”的指针(该指针指向字符串的地址)。这是灾难性的,一旦其中一个对象被销毁,另外个对象str指针便指向了一个危险的地址。
如果采用另外种声明方式:
1: class Word
2: {
3: public:
4: Word(const Word &word);
5: ~Word();
6: private:
7: int cnt;
8: char *str;
9: }
不要进行位拷贝:
1. 当class内含一个
原文:http://www.cnblogs.com/davidsguo008/p/3652773.html