类/结构体含指针时如何编写拷贝构造函数?概念与实现求助
Great question—this is one of the classic "Rule of Three" scenarios in C++, so let's walk through it clearly with examples. The core issue here is the default copy constructor, which does a "shallow copy": it copies the pointer's value directly instead of creating a new copy of the data the pointer points to. This leads to double-free errors when both objects try to delete the same memory block.
Step 1: Fixing the f2 Struct
First, let's look at why your original f2 struct breaks without a custom copy constructor. Here's the problematic code:
#include <cstring> #include <iostream> struct f2 { char* data; // Regular constructor allocates heap memory f2(const char* str) { data = new char[strlen(str) + 1]; strcpy(data, str); } // Destructor frees the heap memory ~f2() { delete[] data; } }; int main() { f2 obj1("Hello World"); f2 obj2 = obj1; // Default shallow copy! // When main ends, both obj1 and obj2 will delete the same data pointer—crash time return 0; }
To fix this, we need to write a deep copy copy constructor that allocates new memory and copies the actual data, not just the pointer. Here's the corrected struct:
struct f2 { char* data; // Regular constructor f2(const char* str) { data = new char[strlen(str) + 1]; strcpy(data, str); } // Custom copy constructor (deep copy) f2(const f2& other) { // 1. Calculate the length of the original data size_t data_len = strlen(other.data) + 1; // 2. Allocate new heap memory for the copy data = new char[data_len]; // 3. Copy the actual content from the original object to the new memory strcpy(data, other.data); } ~f2() { delete[] data; } };
Now when you copy f2 objects, each gets its own independent block of heap memory. No more double-free errors!
Step 2: Copy Constructors for Classes with Pointers
Classes work almost identically to structs here—the only real difference is default access control (structs default to public, classes default to private). Let's adapt the example to a class:
#include <cstring> #include <iostream> class StringWrapper { private: char* buffer; // Private pointer to heap memory public: // Regular constructor StringWrapper(const char* input) { buffer = new char[strlen(input) + 1]; strcpy(buffer, input); } // Custom copy constructor (deep copy) StringWrapper(const StringWrapper& other) { size_t buffer_len = strlen(other.buffer) + 1; buffer = new char[buffer_len]; strcpy(buffer, other.buffer); } // Destructor ~StringWrapper() { delete[] buffer; } // Helper method to show the content void print() const { std::cout << buffer << "\n"; } }; int main() { StringWrapper original("This is a test"); StringWrapper copy = original; original.print(); // Output: This is a test copy.print(); // Output: This is a test (independent memory) return 0; }
Quick Note: The Rule of Three
While you asked specifically about copy constructors, it's worth mentioning that if you write a custom copy constructor, you should also write a custom assignment operator and destructor (this is the Rule of Three). This ensures all operations that copy/move your object handle the heap memory safely.
内容的提问来源于stack exchange,提问作者F.M

