含unique_ptr的类:浅拷贝与深拷贝的差异相关性探讨
unique_ptr Member: The Difference Between Shallow and Deep Copy Let’s break this down clearly, since unique_ptr’s ownership model makes this scenario a classic example of why copy semantics matter so much in C++.
First: Why Shallow Copy Is (By Default) Impossible (and Dangerous If Forced)
unique_ptr is built to enforce exclusive ownership of the memory it points to. By design, it doesn’t have a public copy constructor or copy assignment operator—those are explicitly deleted in the standard library.
So if your class has a unique_ptr member, the compiler will automatically delete your class’s default copy constructor and copy assignment operator too. Try to do something like this, and you’ll hit a compile error:
class MyClass { public: std::unique_ptr<int> data = std::make_unique<int>(42); }; // This won't compile! MyClass a; MyClass b = a; // Error: copy constructor is deleted
But what if you somehow bypassed the compiler checks (like using memcpy to copy the raw bytes of the object)? That’s a manual shallow copy, and it’s a disaster waiting to happen:
- Both
a.dataandb.datawould now point to the sameintin memory. - When one object goes out of scope, its
unique_ptrwill delete the underlyingint. - The other object’s
unique_ptrnow holds a dangling pointer—using it (or letting its destructor run) will cause undefined behavior (usually a double-free crash).
Deep Copy: The Correct Approach for Independent Objects
If you want your class to be copyable, you need to implement deep copy semantics explicitly. That means creating a brand new copy of the memory the unique_ptr points to, so each object owns its own independent resource.
Here’s a straightforward implementation:
class MyClass { public: std::unique_ptr<int> data = std::make_unique<int>(42); // Deep copy constructor MyClass(const MyClass& other) { // Create a new int with the same value as other's data data = std::make_unique<int>(*other.data); } // Deep copy assignment operator MyClass& operator=(const MyClass& other) { if (this != &other) { // Update our data to a copy of other's data *data = *other.data; // For more complex resource types, you'd do: // data = std::make_unique<SomeComplexType>(*other.data); } return *this; } };
Now, when you copy MyClass objects:
- Each object’s
unique_ptrpoints to its own separateintinstance. - Destroying one object has no effect on the other—they’re completely independent.
The Core Correlation Between Shallow/Deep Copy and unique_ptr
The key takeaway here is that unique_ptr’s exclusive ownership model makes shallow copy semantically invalid for any class containing it. Shallow copy would directly violate the "one owner per resource" rule that unique_ptr exists to enforce.
Deep copy, on the other hand, aligns perfectly with making your class copyable while respecting unique_ptr’s semantics—each copy gets its own resource, so no ownership conflicts or dangling pointers arise.
In short: For classes with unique_ptr members, shallow copy is either impossible (thanks to compiler safeguards) or catastrophic if forced. Deep copy is the only valid way to create independent copies of the class.
内容的提问来源于stack exchange,提问作者davidlingg2000

