C++五法则(Rule of Five)

在C++中,​五法则(Rule of Five)​​ 是资源管理类(如管理动态内存、文件句柄等)的核心规则, 专指的是构造函数的数量。

#include <iostream>
#include <utility>  // for std::move

class A {
private:
    int* data;      
    size_t size;   

public:
    // 1. 普通构造函数
    explicit A(size_t sz = 0) : data(nullptr), size(sz) {
        if (sz > 0) {
            data = new int[sz];
            std::fill(data, data + sz, 0);  // 初始化为0
        }
        std::cout << "构造函数: size=" << sz << "\n";
    }

    // 2. 析构函数(Destructor)​
    ~A() {
        delete[] data;
        std::cout << "析构函数: size=" << size << "\n";
    }

    // 3. 拷贝构造函数(Copy Constructor)​
    A(const A& other) : data(nullptr), size(other.size) {
        if (other.size > 0) {
            data = new int[other.size];
            std::copy(other.data, other.data + other.size, data);
        }
        std::cout << "拷贝构造函数: size=" << size << "\n";
    }

    // 4. 拷贝赋值操作符(Copy Assignment Operator)
    A& operator=(const A& other) {
        if (this != &other) {  // 处理自赋值
            delete[] data;     // 释放旧资源
            size = other.size;
            data = new int[size];
            std::copy(other.data, other.data + size, data);
        }
        std::cout << "拷贝赋值操作符: size=" << size << "\n";
        return *this;
    }

    // 5. 移动构造函数(Move Constructor)
    A(A&& other) noexcept : data(other.data), size(other.size) {
        other.data = nullptr;  // 置空源对象指针
        other.size = 0;
        std::cout << "移动构造函数: size=" << size << "\n";
    }

    // 6. 移动赋值操作符(Move Assignment Operator)​
    A& operator=(A&& other) noexcept {
        if (this != &other) { 
            delete[] data;     
            data = other.data;
            size = other.size;
            other.data = nullptr;  // 置空源对象
            other.size = 0;
        }
        std::cout << "移动赋值操作符: size=" << size << "\n";
        return *this;
    }

    // 辅助函数:打印数组地址(验证资源是否转移)
    void print() const {
        std::cout << "data地址: " << data << ", size=" << size << "\n";
    }
};

// 测试函数
int main() {
    std::cout << "----- 测试构造函数 -----\n";
    A a1(3);        // 普通构造函数
    a1.print();

    std::cout << "\n----- 测试拷贝构造函数 -----\n";
    A a2 = a1;      // 拷贝构造函数
    a2.print();

    std::cout << "\n----- 测试移动构造函数 -----\n";
    A a3 = std::move(a1);  // 移动构造函数(a1.data 变为 nullptr)
    a3.print();
    a1.print();  // a1 已失效

    std::cout << "\n----- 测试拷贝赋值操作符 -----\n";
    A a4;
    a4 = a2;        // 拷贝赋值操作符
    a4.print();

    std::cout << "\n----- 测试移动赋值操作符 -----\n";
    A a5;
    a5 = std::move(a2);  // 移动赋值操作符(a2.data 变为 nullptr)
    a5.print();
    a2.print();  // a2 已失效

    std::cout << "\n----- 程序结束,自动调用析构函数 -----\n";
    return 0;
}

关键区别总结

函数作用调用场景资源处理
构造函数分配资源A a1(3);新分配内存
析构函数释放资源对象销毁时自动调用释放内存
拷贝构造函数深拷贝初始化新对象A a2 = a1;复制资源
移动构造函数转移资源初始化新对象A a3 = std::move(a1);接管资源,源对象置空
拷贝赋值操作符深拷贝赋值给已存在对象a4 = a2;释放旧资源后复制新资源
移动赋值操作符转移资源赋值给已存在对象a5 = std::move(a2);释放旧资源后接管新资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值