深入C++拷贝构造函数的总结详解
什么是拷贝构造函数
在 C++ 中,每个类都有至少一个构造函数,负责创建这个类的对象。其中,拷贝构造函数是一种特殊的构造函数,它负责用一个已经存在的对象来初始化一个新的对象。拷贝构造函数的原型为:
类名(const 类名 &obj)
其中,obj 是需要拷贝的对象的引用。
拷贝构造函数的调用时机
当一个对象需要复制到另一个对象时,就会调用该对象的拷贝构造函数。具体包括以下情况:
- 当一个对象作为另一个对象的实参进行传递时,拷贝构造函数会被调用。
- 当一个对象作为函数返回值进行返回时,拷贝构造函数会被调用。
- 当一个对象被另一个对象进行初始化时,拷贝构造函数会被调用。
浅拷贝和深拷贝
拷贝构造函数的实现方式有两种,分别是浅拷贝和深拷贝。它们的区别在于如何复制对象的成员变量。
浅拷贝
浅拷贝就是简单地将源对象的成员变量复制到目标对象中。如果源对象中某个成员变量是一个指针,那么目标对象中的该成员变量将指向与源对象中相同的内存地址。由于两个对象共享同一块内存,因此当其中任何一个对象进行内存释放时,另一个对象的指针也将变为悬空指针。
class ShallowCopy {
public:
int num;
char* str;
ShallowCopy(int n, const char* s) {
num = n;
str = new char[strlen(s) + 1];
strcpy(str, s);
}
// 浅拷贝构造函数
ShallowCopy(const ShallowCopy& obj) {
num = obj.num;
str = obj.str;
}
~ShallowCopy() {
delete[] str;
}
};
int main() {
ShallowCopy obj1(1, "Hello");
ShallowCopy obj2 = obj1;
// 修改 obj1.str 的值
obj1.str[0] = 'h';
cout << obj1.str << endl; // hello
cout << obj2.str << endl; // hello
return 0;
}
深拷贝
深拷贝则是将源对象的成员变量复制到一个新的内存地址中,并将目标对象的成员变量指向该内存地址。由于目标对象与源对象的成员变量指向不同的内存地址,因此它们彼此独立,互不干扰。
class DeepCopy {
public:
int num;
char* str;
DeepCopy(int n, const char* s) {
num = n;
str = new char[strlen(s) + 1];
strcpy(str, s);
}
// 深拷贝构造函数
DeepCopy(const DeepCopy& obj) {
num = obj.num;
str = new char[strlen(obj.str) + 1];
strcpy(str, obj.str);
}
~DeepCopy() {
delete[] str;
}
};
int main() {
DeepCopy obj1(1, "Hello");
DeepCopy obj2 = obj1;
// 修改 obj1.str 的值
obj1.str[0] = 'h';
cout << obj1.str << endl; // hello
cout << obj2.str << endl; // Hello
return 0;
}
示例说明
上面的示例说明了浅拷贝和深拷贝的区别。我们先定义了一个 ShallowCopy
类和一个 DeepCopy
类,它们都有一个 num
整型成员变量和一个 str
字符串成员变量。其中,ShallowCopy
类的拷贝构造函数实现了浅拷贝,DeepCopy
类的拷贝构造函数实现了深拷贝。
在 main
函数中,分别定义了 obj1
和 obj2
对象,并将 obj1
的值赋给了 obj2
。然后,我们修改了 obj1
的 str
成员变量的值,并输出了 obj1
和 obj2
的 str
成员变量的值。由于 ShallowCopy
类的拷贝构造函数实现了浅拷贝,因此 obj2
的 str
指针指向了 obj1
中的 str
指针,它们共享同一块内存,因此修改了 obj1.str
的值后,obj2.str
的值也发生了相应的变化;而 DeepCopy
类的拷贝构造函数实现了深拷贝,因此 obj2
的 str
成员变量指向了一个新的内存地址,它们彼此独立,互不干扰,因此修改了 obj1.str
的值后,obj2.str
的值没有发生变化。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入C++拷贝构造函数的总结详解 - Python技术站