📅  最后修改于: 2023-12-03 15:25:41.996000             🧑  作者: Mango
在大多数情况下,C++ 的默认复制构造函数会足够满足我们的需求。但在某些情况下,我们可能需要编写自己的副本构造函数。
副本构造函数是一种特殊的成员函数,它用于在创建对象的新副本时执行必要的内存和资源分配操作。当我们创建一个新对象并将其初始化为另一个对象的副本时,编译器会调用副本构造函数。
下面是一些情况下,我们可能需要编写自己的副本构造函数。
当我们的类包含裸指针时,复制对象可能会导致内存泄漏或段错误。这是因为默认的复制构造函数只会简单地复制指针的值,而没有复制指针所指向的数据。为了避免这种情况,我们需要编写自己的副本构造函数来复制指针所指向的数据。
class MyClass {
public:
MyClass();
MyClass(const MyClass& other);
~MyClass();
private:
int* m_ptr;
};
MyClass::MyClass() {
m_ptr = new int;
}
MyClass::MyClass(const MyClass& other) {
m_ptr = new int;
*m_ptr = *(other.m_ptr);
}
MyClass::~MyClass() {
delete m_ptr;
}
如果我们的类含有比如 mutex 等资源,那么在复制对象时会导致不必要的麻烦。在这种情况下,我们需要编写自己的副本构造函数,以确保资源得到正确的分配和释放。
class MyClass {
public:
MyClass();
MyClass(const MyClass& other);
~MyClass();
private:
std::mutex m_mutex;
};
MyClass::MyClass() {
// Do nothing
}
MyClass::MyClass(const MyClass& other) {
// Acquire the mutex in the other object
other.m_mutex.lock();
// Copy the member variables
// ...
// Release the mutex in the other object
other.m_mutex.unlock();
}
MyClass::~MyClass() {
// Do nothing
}
如果我们的类有一个成员变量是不可复制的,也就是说,它的副本构造函数是私有的或被删除的,那么我们需要为类编写自己的副本构造函数。
class NonCopyable {
public:
NonCopyable() {}
NonCopyable(const NonCopyable&) = delete;
NonCopyable& operator=(const NonCopyable&) = delete;
};
class MyClass {
public:
MyClass();
MyClass(const MyClass& other);
~MyClass();
private:
NonCopyable m_nc;
};
MyClass::MyClass() {
// Do nothing
}
MyClass::MyClass(const MyClass& other) {
// Copy the member variables except m_nc
// ...
}
MyClass::~MyClass() {
// Do nothing
}
在需要执行特殊操作或处理特殊情况的情况下,我们需要编写自己的副本构造函数。但是,在大多数情况下,我们可以信任默认的复制构造函数。