[c++ 笔记]shared_ptr 理解创建时即捕获析构动作

1. shared_ptr

shared_ptr 是c++ 管理资源的利器,也是C++ 相对于其他语言最大区别的RAII特性的最直观体现。
shared_ptr一大好处是其创建时即捕获析构动作,即使基类析构函数不是虚函数,也能正确完成子类与析类的析构动作。如下:

class Base
{
public:
    ~Base()
    {
        std::cout << "Base destructor" << std::endl;
    }
};

class Derived : public Base
{
public:
    ~Derived()
    {
        std::cout << "Derived destructor" << std::endl;
    }
};

void virtual_destructor()
{
    {
        std::cout << "--------------------" << std::endl;
        std::shared_ptr<Base> sharedA(new Derived);
    }

    std::cout << "--------------------" << std::endl;
    Base * a = new Derived;
    delete a;
}

Output:

--------------------
Derived destructor
Base destructor
--------------------
Base destructor

对比可见,由于基类析构函数不是虚函数,因此对基类原生指针的析构,并未正确的析构子类。而利用shared_ptr则完成正确动作。

2.原理

以下代码模拟shared_ptr的析构原理。

template <typename T>
class simple_ptr_internal_interface {
public:
    virtual T* get() = 0;
    virtual void destruct() = 0;
}; // class simple_ptr_internal_interface

template <typename T, typename D>
class simple_ptr_internal: public simple_ptr_internal_interface {
public:
    simple_ptr_internal(T* p, D d): pointer(p), deleter(std::move(d)) {}

    virtual T* get() override { return pointer; }
    virtual void destruct() override { deleter(pointer); }

private:
    T* pointer;
    D deleter;
}; // class simple_ptr_internal

template <typename T>
class simple_ptr {
    template <typename U>
    struct DefaultDeleter {
        void operator()(T* t) { delete static_cast<U*>(t); }
    };

    template <typename Derived>
    using DefaultInternal = simple_ptr_internal<T, DefaultDeleter<Derived>>;

public:
    template <typename Derived>
    simple_ptr(Derived* d): internal(new DefaultInternal<Derived>{d}) {}

    ~simple_ptr() { this->destruct(); }

private:
    void destruct() { internal->destruct(); }

    simple_ptr_internal_interface* internal;
}; 

从以上代码可见,shared_ptr在创建时实际保存了所创建的子类类型的指针,并在最终删除对象时在删除器中调用。因此,可正确的析构子类与基类。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值