09_其他特殊函数

存在管理资源的类一般还会定义一个swap函数。

定义 swap 函数的原因

在管理资源的类中定义 swap 函数主要有以下几个重要原因:

1. 高效交换资源

通常在进行资源交换时,若采用常规的复制和销毁操作,开销会很大。而使用 swap 函数仅需交换资源的内部指针或者引用,时间复杂度为 O(1),能显著提升效率。

2. 异常安全性

在交换资源时,swap 函数可以保证操作具有强异常安全性。也就是说,若交换过程中出现异常,对象的状态不会发生改变。

3. 与标准库兼容

标准库中的算法(如 std::sortstd::reverse 等)常常会使用 swap 来交换对象。为自定义的资源管理类定义 swap 函数,能让该类更好地与标准库算法协同工作。

示例代码

以下是一个简单的资源管理类 ResourceManager,并定义了 swap 函数:

#include <iostream>
#include <utility>

// 模拟资源类
class Resource {
public:
    Resource(int value) : data(value) {
        std::cout << "Resource created with value: " << data << std::endl;
    }
    ~Resource() {
        std::cout << "Resource destroyed with value: " << data << std::endl;
    }
    int getData() const {
        return data;
    }
private:
    int data;
};

// 资源管理类
class ResourceManager {
public:
    ResourceManager(int value) : resource(new Resource(value)) {}
    ~ResourceManager() {
        delete resource;
    }

    // 拷贝构造函数
    ResourceManager(const ResourceManager& other) : resource(new Resource(other.resource->getData())) {}

    // 拷贝赋值运算符
    ResourceManager& operator=(ResourceManager other) {
        swap(*this, other);
        return *this;
    }

    // 定义 swap 函数
    friend void swap(ResourceManager& first, ResourceManager& second) {
        using std::swap;
        swap(first.resource, second.resource);
    }

    int getData() const {
        return resource->getData();
    }
private:
    Resource* resource;
};

int main() {
    ResourceManager rm1(10);
    ResourceManager rm2(20);

    std::cout << "Before swap: rm1 data = " << rm1.getData() << ", rm2 data = " << rm2.getData() << std::endl;
    swap(rm1, rm2);
    std::cout << "After swap: rm1 data = " << rm1.getData() << ", rm2 data = " << rm2.getData() << std::endl;

    return 0;
}

代码解释

  • Resource 类:模拟了一个资源,其构造函数和析构函数会输出相应信息,方便观察资源的创建和销毁过程。
  • ResourceManager 类:负责管理 Resource 对象,包含一个指向 Resource 的指针。
    • 拷贝构造函数:通过深拷贝的方式创建新的 Resource 对象。
    • 拷贝赋值运算符:采用了 “拷贝并交换” 技术,借助 swap 函数实现资源的交换。
    • swap 函数:交换两个 ResourceManager 对象的 resource 指针,避免了资源的复制和销毁操作。

在 main 函数中,创建了两个 ResourceManager 对象 rm1 和 rm2,交换它们的资源后,输出交换前后的数据,以此验证 swap 函数的功能。

参考

https://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom?rq=1

https://www.bookstack.cn/read/CPlusPlusThings/86395c5695fa6630.md

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值