深拷贝需手动实现拷贝构造函数和赋值操作符,为指针成员分配独立内存并复制数据,避免多对象共享同一内存导致的释放错误;浅拷贝仅复制指针值,是默认行为,易引发野指针和重复释放;现代C++推荐使用string、vector等RAII容器自动实现深拷贝,简化内存管理。

在C++中,深拷贝和浅拷贝主要与对象中指针成员的复制方式有关。默认的拷贝构造函数和赋值操作符执行的是浅拷贝,这在涉及动态内存时可能导致问题。要实现深拷贝,需要手动定义拷贝构造函数和赋值操作符。
当类包含指针成员时,编译器自动生成的拷贝构造函数和赋值操作符只会复制指针的值(即地址),而不是它指向的数据。这称为浅拷贝。
问题:多个对象指向同一块内存,一个对象释放后,其他对象的指针就变成野指针。例如:
<font face="Courier New">
class String {
private:
char* data;
public:
String(const char* str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
}
// 编译器生成的拷贝构造函数是浅拷贝
};
</font>如果使用默认拷贝:
立即学习“C++免费学习笔记(深入)”;
<font face="Courier New">
String s1("hello");
String s2 = s1; // 浅拷贝,s1 和 s2 的 data 指向同一内存
</font>当 s1 或 s2 析构时,同一块内存会被释放两次,导致未定义行为。
为了安全复制指针所指向的内容,必须实现深拷贝——为新对象分配独立内存,并复制数据。
需要手动定义:
这被称为“三法则”。
示例:
<font face="Courier New">
class String {
private:
char* data;
public:
String(const char* str = "") {
data = new char[strlen(str) + 1];
strcpy(data, str);
}
<pre class='brush:php;toolbar:false;'>// 拷贝构造函数:深拷贝
String(const String& other) {
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}
// 赋值操作符:深拷贝,注意自我赋值
String& operator=(const String& other) {
if (this != &other) { // 防止自赋值
delete[] data; // 释放原内存
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}
return *this;
}
// 析构函数
~String() {
delete[] data;
}};
现在 s2 = s1 会创建独立副本,互不影响。
使用标准库容器(如 std::string、std::vector)可以自动管理内存,避免手动实现深拷贝。
例如:
<font face="Courier New">
class Person {
std::string name; // 自动深拷贝
std::vector<int> scores;
public:
Person(const std::string& n) : name(n) {}
// 无需手动定义拷贝构造、赋值、析构
};
</font>std::string 的拷贝构造函数已经实现了深拷贝,编译器生成的默认函数即可正确工作。
深拷贝通过为指针成员分配新内存并复制内容来实现,需手动编写拷贝构造函数和赋值操作符。浅拷贝只复制指针本身,是默认行为,容易引发内存错误。优先使用 RAII 类型(如 string、vector)可自动处理深拷贝,减少错误。
基本上就这些。
以上就是C++如何在语法中实现深拷贝和浅拷贝的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号