Effective C++ 条款 14:在资源管理类中小心 Copying 行为

条款 14:在资源管理类中小心 Copying 行为


核心思想

  • RAII(Resource Acquisition Is Initialization)对象的复制行为决定了其管理资源的复制行为。
  • 在设计 RAII 类时,需仔细考虑是否需要支持复制操作以及如何实现复制。

RAII 对象的复制策略

  1. 抑制 Copying

    • 禁止 RAII 对象被复制,从而避免资源的重复释放。
    • 通常通过将复制构造函数和复制赋值操作符声明为 delete

    示例:禁止复制

    class ResourceGuard {
    public:
      ResourceGuard(const ResourceGuard&) = delete;
      ResourceGuard& operator=(const ResourceGuard&) = delete;
    };
    
  2. 引用计数

    • 多个 RAII 对象共享同一个资源,通过引用计数控制资源的生命周期。
    • 当引用计数降为 0 时,释放资源。
    • 常见实现:std::shared_ptr

    示例:引用计数

    class SharedResource {
    private:
      std::shared_ptr<Resource> resource;
    public:
      SharedResource(Resource* res) : resource(res) {}
    };
    
  3. 深拷贝

    • 复制 RAII 对象时创建资源的新副本,两个对象互相独立。
    • 通常适用于需要多个独立资源实例的场景。

    示例:深拷贝

    class DeepCopyResource {
    private:
      Resource* resource;
    public:
      DeepCopyResource(const DeepCopyResource& other) 
        : resource(new Resource(*other.resource)) {}
      DeepCopyResource& operator=(const DeepCopyResource& other) {
        if (this != &other) {
          delete resource;
          resource = new Resource(*other.resource);
        }
        return *this;
      }
    };
    
  4. 转移所有权

    • 使用移动语义(C++11 引入的 std::move)将资源的所有权从一个 RAII 对象转移到另一个。
    • 通常适用于 std::unique_ptr 等场景。

    示例:转移所有权

    class UniqueResource {
    private:
      std::unique_ptr<Resource> resource;
    public:
      UniqueResource(std::unique_ptr<Resource> res) : 
      	resource(std::move(res)) {}
    };
    

设计建议

  1. 明确 Copying 行为

    • 根据资源的特性决定 RAII 对象是否需要支持复制以及如何实现复制。
    • 默认禁止复制,除非明确需要。
  2. 优先使用标准智能指针

    • 对于大多数场景,std::shared_ptrstd::unique_ptr 是管理资源的首选。
  3. 小心处理动态分配的资源

    • 确保复制行为不会引发资源泄漏或未定义行为。

总结

  • RAII 对象的复制行为与其管理的资源密切相关。
  • 常见策略包括抑制复制、引用计数、深拷贝和转移所有权。
  • 设计 RAII 类时应根据实际需求选择合适的复制策略,避免资源管理问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值