unique_ptr实现Impl模式时遇到的问题分析

背景

对于类的设计与定义,我们习惯上使用“指向实现的指针”, 或者叫PImpl。例如下面的类:

// widget.h(接口)
class widget {
   
    // 公开成员
private:
    struct impl;  // 实现类的前置声明
    impl* ptr;
};
// widget.cpp(实现)
struct widget::impl {
   
   // 实现细节
};

1、对于impl类的改动,不会影响到widget类相应编绎单元的重新编绎,从编绎角度能够较大提供编绎效率。
2、有利于构建稳定的ABI接口。即是某个库使用了impl,则更新了impl的实现之后,新版本库能够兼容旧的ABI。

问题

正常代码

为了对比下面智能指针代码,这里给出一个正常使用raw pointer的示例代码

//widget.h
struct Impl;
class 
  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
`std::unique_ptr` 是一个模板类,它的实现相对来说比较复杂。下面是一个简单的 `unique_ptr` 的实现,仅供参考: ```c++ template<typename T> class unique_ptr { public: explicit unique_ptr(T* ptr = nullptr) : ptr_(ptr) {} ~unique_ptr() { delete ptr_; } unique_ptr(const unique_ptr&) = delete; unique_ptr& operator=(const unique_ptr&) = delete; unique_ptr(unique_ptr&& other) : ptr_(other.ptr_) { other.ptr_ = nullptr; } unique_ptr& operator=(unique_ptr&& other) { if (this != &other) { delete ptr_; ptr_ = other.ptr_; other.ptr_ = nullptr; } return *this; } T* operator->() const { return ptr_; } T& operator*() const { return *ptr_; } T* get() const { return ptr_; } void reset(T* ptr = nullptr) { delete ptr_; ptr_ = ptr; } private: T* ptr_; }; ``` 这个 `unique_ptr` 类模板实现了动态分配内存的功能,它会在离开作用域自动释放内存。在这个实现中,我们定义了一个指针成员变量 `ptr_`,用于保存动态分配的内存地址。在默认构造函数中,我们将 `ptr_` 初始化为 `nullptr`。在析构函数中,我们通过 `delete` 操作符释放 `ptr_` 所指向的内存。注意,在拷贝构造函数和赋值操作符中,我们使用 `delete` 关键字将其禁止,确保 `unique_ptr` 不会被拷贝或赋值。在移动构造函数和移动赋值操作符中,我们将 `ptr_` 的值从另一个 `unique_ptr` 对象中移动过来,并将另一个对象的指针成员变量设置为 `nullptr`,避免出现野指针。在 `reset` 成员函数中,我们首先使用 `delete` 释放 `ptr_` 所指向的内存,然后将 `ptr_` 指向新的内存地址。最后,我们还实现了 `operator->`、`operator*` 和 `get` 成员函数,分别用于获取指向内存的指针、操作内存和获取指针本身。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值