Effective C++ 条款 25:考虑写出一个不抛异常的 swap 函数

条款 25:考虑写出一个不抛异常的 swap 函数

核心思想

  1. 效率提升

    • 当标准库的 std::swap 对你的类型效率不高时,应提供一个更高效的自定义 swap 函数。
  2. 异常安全

    • 确保自定义的 swap 函数不会抛出异常,以避免潜在的不确定性和资源泄漏。
  3. 成员函数与非成员函数

    • 提供一个 member swap 函数用于高效交换对象内部数据,同时提供一个 non-member swap 函数调用前者。
  4. std::swap 的特化

    • 对于用户定义类型,特化 std::swap,以便使用更高效的交换逻辑。
  5. 最佳实践

    • 使用 using std::swap 声明后,调用无命名空间修饰的 swap 函数,确保选择合适的版本。

示例代码

#include <algorithm>
#include <iostream>

class Widget {
public:
    Widget(int data = 0) : data_(new int(data)) {}
    ~Widget() { delete data_; }
    
    Widget(const Widget& rhs) : data_(new int(*rhs.data_)) {}
    Widget& operator=(Widget rhs) { // 使用 copy-and-swap 技术
        swap(rhs);
        return *this;
    }
    
    void swap(Widget& other) noexcept { // 成员 swap
        std::swap(data_, other.data_);
    }
    
    int getData() const { return *data_; }

private:
    int* data_;
};

// 非成员 swap 函数
void swap(Widget& lhs, Widget& rhs) noexcept {
    lhs.swap(rhs); // 调用成员 swap
}

namespace std { // 针对 Widget 特化 std::swap
    template <>
    void swap<Widget>(Widget& lhs, Widget& rhs) noexcept {
        lhs.swap(rhs); // 调用成员 swap
    }
}

int main() {
    Widget w1(10), w2(20);
    using std::swap;
    
    swap(w1, w2); // 调用非成员 swap 或 std::swap
    
    std::cout << "w1: " << w1.getData() << ", w2: " << w2.getData() << std::endl;
    return 0;
}

说明

  1. 效率优势

    • std::swap 使用拷贝构造和赋值操作符,效率可能较低。通过提供 member swap 函数,只需交换指针或其他轻量资源,效率显著提升。
  2. 异常安全

    • 自定义的 swap 函数使用 noexcept 关键字,明确保证不抛出异常。
  3. 成员与非成员的关系

    • member swap 是具体的实现逻辑,non-member swap 是接口,增强了函数调用的灵活性。
  4. 特化 std::swap

    • std::swap 提供特化,允许 STL 容器中的对象使用自定义的高效交换逻辑。
  5. using std::swap 的使用

    • 声明 using std::swap 后调用无命名空间修饰的 swap,让编译器优先选择用户定义的 swap

注意事项

  1. 不要在 std 命名空间中添加新内容

    • 仅允许对已有类型进行特化,切勿向 std 中引入新的类型或函数。
  2. 防止异常传播

    • 确保所有与 swap 相关的操作不会抛出异常,否则可能破坏程序的异常安全性。

结论

  • 提供一个不抛异常的 swap 函数能显著提升性能和安全性。
  • 使用 member swapnon-member swap 配合设计,以增强灵活性和代码重用性。
  • 特化 std::swap 以支持更高效的交换行为,同时遵循 C++ 标准的规范。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值