在C++中,复制构造函数是一种特殊的成员函数,用于创建一个新对象作为现有对象的副本。它在以下情况下被调用:
复制构造函数的典型声明形式如下:
ClassName(const ClassName &other);
其中ClassName
是类名,other
是对另一个同类对象的引用。
复制构造函数的作用:
复制构造函数的类型:
假设我们有一个简单的类MyClass
,其中包含一个动态分配的内存:
#include <iostream>
class MyClass {
private:
int* data;
int size;
public:
// 构造函数
MyClass(int s) : size(s), data(new int[s]) {
for (int i = 0; i < size; ++i) {
data[i] = i;
}
}
// 复制构造函数(深拷贝)
MyClass(const MyClass& other) : size(other.size), data(new int[other.size]) {
for (int i = 0; i < size; ++i) {
data[i] = other.data[i];
}
}
// 析构函数
~MyClass() {
delete[] data;
}
// 打印数据
void print() const {
for (int i = 0; i < size; ++i) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
};
int main() {
MyClass obj1(5);
obj1.print(); // 输出: 0 1 2 3 4
MyClass obj2 = obj1; // 调用复制构造函数
obj2.print(); // 输出: 0 1 2 3 4
return 0;
}
问题:如果未定义复制构造函数,编译器会生成默认的复制构造函数,执行浅拷贝。这可能导致两个对象共享同一内存地址,当其中一个对象被销毁时,另一个对象的指针将变成悬空指针。
解决方法:
std::unique_ptr
或std::shared_ptr
)来自动管理内存,避免手动管理内存带来的问题。例如,使用std::unique_ptr
重写上述示例:
#include <iostream>
#include <memory>
class MyClass {
private:
std::unique_ptr<int[]> data;
int size;
public:
MyClass(int s) : size(s), data(new int[s]) {
for (int i = 0; i < size; ++i) {
data[i] = i;
}
}
// 复制构造函数(深拷贝)
MyClass(const MyClass& other) : size(other.size), data(new int[other.size]) {
for (int i = 0; i < size; ++i) {
data[i] = other.data[i];
}
}
void print() const {
for (int i = 0; i < size; ++i) {
std::cout << data[i] << " ";
}
std::cout << std::endl;
}
};
int main() {
MyClass obj1(5);
obj1.print(); // 输出: 0 1 2 3 4
MyClass obj2 = obj1; // 调用复制构造函数
obj2.print(); // 输出: 0 1 2 3 4
return 0;
}
通过这种方式,可以确保每个对象都有自己独立的内存空间,避免潜在的内存问题。
领取专属 10元无门槛券
手把手带您无忧上云