1.我们没有在类中实现拷贝构造函数,那么编译器会自动产生一个默认拷贝构造函数
该拷贝构造函数将执行数据成员的逐个成员复制。类似于以下代码:
1 TPerson::TPerson(const TPerson &sourse) 2 :birthDate(sourse.birthDate),name(sourse.name),ssn(sourse.ssn),address(sourse.address) 3 {}
称为浅复制;
除了name和address数据成员外,这种复制不会有问题。
存在的问题:
1 void foo(TPerson thePerson) 2 { 3 //此处代码不重要 4 } 5 6 void main() 7 { 8 TPerson bar("Foo Bar", "Unknown", "41422222", "6-6-99"); 9 foo(bar); 10 }
当要离开foo()函数时,局部变量thePerson即将离开作用域,因此将调用它的析构函数。
该析构函数释放name和address所指的内存。但是源对象bar仍在使用,但它的name和address已经被析构函数删除,便产生了悬挂引用
,这就是默认拷贝构造函数(或浅复制)存在的问题。
但如果对象不包含任何指针和引用,浅复制完全满足需要。
2.深复制:
1 void main() 2 { 3 TPerson bar("Foo Bar", "Unknown", "41422222", "6-6-99"); 4 foo(bar); 5 } 6 7 8 TPerson::TPerson(const TPerson& sourse) 9 :ssn(sourse.ssn), birthDate(sourse.birthDate) 10 { 11 //如果不是NULL,复制name和address。 12 //需要检查源是否包含非零指针,然后为其分配内存和复制数据。 13 //我们已为此编好strdup(),现在可以直接使用他。 14 this->name = source.name ? strdup(source.name) : 0; 15 this->address = source.address ? strdup(source.address) : 0; 16 }