一、拷贝构造函数基础

1.1 拷贝构造函数的定义和声明

class CopyConstructorBasics {
private:
    int* data;
    size_t size;
    std::string name;
    
public:
    // 标准拷贝构造函数声明
    CopyConstructorBasics(const CopyConstructorBasics& other);
    
    // 其他可能的声明形式(不常用)
    // CopyConstructorBasics(CopyConstructorBasics& other);           // 非const引用
    // CopyConstructorBasics(const CopyConstructorBasics& other, int = 0); // 带默认参数
    // CopyConstructorBasics(volatile const CopyConstructorBasics& other); // volatile
    
    // 普通构造函数
    CopyConstructorBasics(size_t s, const std::string& n) 
        : data(new int[s]()), size(s), name(n) {
        std::cout << "Normal constructor\n";
    }
    
    // 析构函数
    ~CopyConstructorBasics() {
        delete[] data;
        std::cout << "Destructor for " << name << "\n";
    }
};
 
// 拷贝构造函数实现
CopyConstructorBasics::CopyConstructorBasics(const CopyConstructorBasics& other)
    : size(other.size)
    , name(other.name + "_copy") {
    std::cout << "Copy constructor\n";
    
    // 深拷贝
    data = new int[size];
    std::copy(other.data, other.data + size, data);
}

1.2 拷贝构造函数的调用时机

class CopyScenarios {
    std::string name;
    
public:
    CopyScenarios(const std::string& n) : name(n) {
        std::cout << "Constructor: " << name << "\n";
    }
    
    CopyScenarios(const CopyScenarios& other) : name(other.name + "_copy") {
        std::cout << "Copy constructor: " << name << "\n";
    }
    
    ~CopyScenarios() {
        std::cout << "Destructor: " << name << "\n";
    }
    
    static void demonstrateCopyScenarios() {
        std::cout << "=== Scenario 1: Direct initialization ===\n";
        CopyScenarios obj1("obj1");
        CopyScenarios obj2(obj1);  // 拷贝构造
        
        std::cout << "\n=== Scenario 2: Copy initialization ===\n";
        CopyScenarios obj3 = obj1;  // 拷贝构造(不是赋值)
        
        std::cout << "\n=== Scenario 3: Function parameter (pass by value) ===\n";
        auto func = [](CopyScenarios param) {  // 参数通过拷贝构造传入
            std::cout << "Inside function\n";
        };
        func(obj1);
        
        std::cout << "\n=== Scenario 4: Return by value ===\n";
        auto createObject = []() -> CopyScenarios {
            CopyScenarios temp("temp");
            return temp;  // 可能触发拷贝构造(或被优化)
        };
        CopyScenarios obj4 = createObject();
        
        std::cout << "\n=== Scenario 5: Container operations ===\n";
        std::vector<CopyScenarios> vec;
        vec.reserve(3);  // 预分配避免重新分配
        vec.push_back(obj1);  // 拷贝构造
        vec.push_back(CopyScenarios("temp2"));  // 可能移动构造
        
        std::cout << "\n=== Scenario 6: Exception throwing ===\n";
        try {
            throw obj1;  // 拷贝构造异常对象
        } catch (CopyScenarios e) {  // 再次拷贝构造
            std::cout << "Caught exception\n";
        }
        
        std::cout << "\n=== End of demonstration ===\n";
    }
};

二、深拷贝与浅拷贝

2.1 浅拷贝的问题

class ShallowCopyProblem {
private:
    int* data;
    size_t size;
    
public:
    ShallowCopyProblem(size_t s) : size(s), data(new int[s]) {
        std::cout << "Constructor: allocated " << size << " ints\n";
    }
    
    // 编译器生成的默认拷贝构造函数(浅拷贝)
    // ShallowCopyProblem(const ShallowCopyProblem& other)
    //     : data(other.data)    // 危险!只拷贝指针
    //     , size(other.size) {}
    
    ~ShallowCopyProblem() {
        delete[] data;  // 双重删除问题!
        std::cout << "Destructor: freed memory\n";
    }
    
    static void demonstrateProblem() {
        ShallowCopyProblem obj1(10);
        {
            ShallowCopyProblem obj2(obj1);  // 浅拷贝
            // obj1和obj2的data指向同一块内存
        }  // obj2析构,删除data
        // obj1的data现在是悬空指针!
        // obj1析构时会再次删除,导致未定义行为
    }
};

2.2 深拷贝实现

class DeepCopy {
private:
    int* data;
    size_t size;
    size_t capacity;
    std::string* names;
    
    // 嵌套类也需要深拷贝
    class Node {
    public:
        int value;
        Node* next;
        
        Node(int v) : value(v), next(nullptr) {}
        
        // Node的深拷贝
        Node* deepCopy() const {
            Node* newNode = new Node(value);
            if (next) {
                newNode->next = next->deepCopy();
            }
            return newNode;
        }
    };
    
    Node* head;
    
public:
    DeepCopy(size_t s) 
        : size(s)
        , capacity(s * 2)
        , data(new int[capacity]())
        , names(new std::string[size])
        , head(nullptr) {
        std::cout << "Constructor\n";
    }
    
    // 深拷贝构造函数
    DeepCopy(const DeepCopy& other)
        : size(other.size)
        , capacity(other.capacity) {
        std::cout << "Deep copy constructor\n";
        
        // 1. 拷贝动态数组
        data = new int[capacity];
        std::copy(other.data, other.data + size, data);
        
        // 2. 拷贝字符串数组
        names = new std::string[size];
        std::copy(other.names, other.names + size, names);
        
        // 3. 拷贝链表
        if (other.head) {
            head = other.head->deepCopy();
        } else {
            head = nullptr;
        }
    }
    
    ~DeepCopy() {
        delete[] data;
        delete[] names;
        
        // 删除链表
        while (head) {
            Node* temp = head;
            head = head->next;
            delete temp;
        }
        
        std::cout << "Destructor\n";
    }
    
    // 辅助函数:添加节点
    void addNode(int value) {
        Node* newNode = new Node(value);
        newNode->next = head;
        head = newNode;
    }
};

2.3 智能指针与拷贝

class SmartPointerCopy {
private:
    // unique_ptr:独占所有权,不能拷贝
    std::unique_ptr<int> uniqueData;
    
    // shared_ptr:共享所有权,可以拷贝
    std::shared_ptr<int> sharedData;
    
    // 自定义删除器的shared_ptr
    std::shared_ptr<int[]> arrayData;
    
    // weak_ptr:弱引用
    std::weak_ptr<int> weakData;
    
public:
    SmartPointerCopy() 
        : uniqueData(std::make_unique<int>(42))
        , sharedData(std::make_shared<int>(100))
        , arrayData(new int[10], std::default_delete<int[]>()) {
        weakData = sharedData;
    }
    
    // 拷贝构造函数
    SmartPointerCopy(const SmartPointerCopy& other)
        : uniqueData(other.uniqueData ? 
                    std::make_unique<int>(*other.uniqueData) : nullptr)  // 深拷贝
        , sharedData(other.sharedData)  // 共享所有权
        , arrayData(other.arrayData)     // 共享所有权
        , weakData(other.weakData) {     // 弱引用拷贝
        
        std::cout << "Copy constructor\n";
        std::cout << "Shared count: " << sharedData.use_count() << "\n";
    }
    
    // 演示不同的拷贝策略
    void demonstrateCopyStrategies() {
        // 策略1:深拷贝(独占资源)
        class DeepCopyStrategy {
            std::unique_ptr<std::vector<int>> data;
        public:
            DeepCopyStrategy() : data(std::make_unique<std::vector<int>>()) {}
            
            DeepCopyStrategy(const DeepCopyStrategy& other)
                : data(std::make_unique<std::vector<int>>(*other.data)) {}
        };
        
        // 策略2:共享资源(引用计数)
        class SharedStrategy {
            std::shared_ptr<std::vector<int>> data;
        public:
            SharedStrategy() : data(std::make_shared<std::vector<int>>()) {}
            
            SharedStrategy(const SharedStrategy& other) = default;  // 共享
        };
        
        // 策略3:写时拷贝(COW)
        class COWStrategy {
            struct Data {
                std::vector<int> vec;
                mutable std::mutex mtx;
            };
            std::shared_ptr<Data> data;
            
        public:
            COWStrategy() : data(std::make_shared<Data>()) {}
            
            COWStrategy(const COWStrategy& other) : data(other.data) {}
            
            void modify(size_t index, int value) {
                if (data.use_count() > 1) {
                    // 需要拷贝
                    data = std::make_shared<Data>(*data);
                }
                std::lock_guard<std::mutex> lock(data->mtx);
                data->vec[index] = value;
            }
        };
    }
};

三、拷贝构造函数的特殊情况

3.1 禁用拷贝构造

class NoCopy {
private:
    std::unique_ptr<int> data;
    
public:
    NoCopy() : data(std::make_unique<int>(42)) {}
    
    // 方法1:删除拷贝构造函数(C++11)
    NoCopy(const NoCopy&) = delete;
    NoCopy& operator=(const NoCopy&) = delete;
    
    // 方法2:私有化(C++98方式,不推荐)
    // private:
    //     NoCopy(const NoCopy&);
    //     NoCopy& operator=(const NoCopy&);
};
 
// 单例模式示例
class Singleton {
private:
    static Singleton* instance;
    
    Singleton() = default;
    
    // 禁止拷贝
    Singleton(const Singleton&) = delete;
    Singleton& operator=(const Singleton&) = delete;
    
public:
    static Singleton& getInstance() {
        static Singleton instance;  // C++11保证线程安全
        return instance;
    }
};
 
// 使用基类禁用拷贝
class NonCopyable {
protected:
    NonCopyable() = default;
    ~NonCopyable() = default;
    
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable& operator=(const NonCopyable&) = delete;
};
 
class MyClass : private NonCopyable {
    // 自动继承不可拷贝特性
};

3.2 拷贝构造函数与继承

class Base {
protected:
    int* baseData;
    std::string baseName;
    
public:
    Base(const std::string& name) 
        : baseData(new int(100))
        , baseName(name) {
        std::cout << "Base constructor\n";
    }
    
    // 基类拷贝构造函数
    Base(const Base& other)
        : baseData(new int(*other.baseData))
        , baseName(other.baseName + "_base_copy") {
        std::cout << "Base copy constructor\n";
    }
    
    virtual ~Base() {
        delete baseData;
        std::cout << "Base destructor\n";
    }
};
 
class Derived : public Base {
private:
    double* derivedData;
    std::vector<int> vec;
    
public:
    Derived(const std::string& name) 
        : Base(name)
        , derivedData(new double(3.14))
        , vec{1, 2, 3} {
        std::cout << "Derived constructor\n";
    }
    
    // 派生类拷贝构造函数
    Derived(const Derived& other)
        : Base(other)  // 显式调用基类拷贝构造函数
        , derivedData(new double(*other.derivedData))
        , vec(other.vec) {
        std::cout << "Derived copy constructor\n";
    }
    
    ~Derived() {
        delete derivedData;
        std::cout << "Derived destructor\n";
    }
};
 
// 切片问题
class SlicingProblem {
public:
    static void demonstrate() {
        Derived d("derived");
        
        // 对象切片
        Base b = d;  // 只拷贝Base部分,丢失Derived部分
        
        // 正确做法:使用指针或引用
        Base* ptr = new Derived(d);  // 完整拷贝
        Base& ref = d;               // 引用原对象
        
        delete ptr;
    }
};

3.3 拷贝构造函数与异常安全