实战c++中的智能指针unique_ptr系列-- unique_ptr的get_deleter方法(自定义删除器)

原文转载于:https://blog.csdn.net/wangshubo1989/article/details/50408182

unique_ptr的成员函数在上一篇博客中几乎全部涵盖,其实还有一个很有踢掉,即std::unique_ptr::get_deleter

字面已经很明显了,就获得deleter: 
Returns the stored deleter

The stored deleter is a callable object. A functional call to this object with a single argument of member type pointer is expected to delete the managed object, and is automatically called when the unique_ptr is itself destroyed, assigned a new value, or resetted while non-empty.

直接看例子:

#include <iostream>
#include <memory>

class state_deleter {  // a deleter class with state
    int count_;
public:
    state_deleter() : count_(0) {}
    template <class T>
    void operator()(T* p) {
        std::cout << "[deleted #" << ++count_ << "]\n";
        delete p;
    }
};

int main() {
    state_deleter del;

    std::unique_ptr<int> p;   // uses default deleter

    // alpha and beta use independent copies of the deleter:
    std::unique_ptr<int, state_deleter> alpha(new int);
    std::unique_ptr<int, state_deleter> beta(new int, alpha.get_deleter());
    return 0;
}

运行程序,输出结果: 
[deleted #1] 
[deleted #1] 
说明了,在函数结束的时候,alpha beta的析构函数被调用了,而且析构函数是我们自己定义的类。

在上面的代码上加入对alpha beta的操作:

int main() {
    state_deleter del;

    std::unique_ptr<int> p;   // uses default deleter

    // alpha and beta use independent copies of the deleter:
    std::unique_ptr<int, state_deleter> alpha(new int);
    std::unique_ptr<int, state_deleter> beta(new int, alpha.get_deleter());


    std::cout << "resetting alpha..."; alpha.reset(new int);
    std::cout << "resetting beta..."; beta.reset(new int);

    return 0;
}

输出: 
resetting alpha…[deleted #1] 
resetting beta…[deleted #1] 
[deleted #2] 
[deleted #2] 
说明在reset方法后,也调用了自定义的析构~

再继续添加代码:


#include <iostream>
#include <memory>

class state_deleter {  // a deleter class with state
    int count_;
public:
    state_deleter() : count_(0) {}
    template <class T>
    void operator()(T* p) {
        std::cout << "[deleted #" << ++count_ << "]\n";
        delete p;
    }
};

int main() {
    state_deleter del;

    std::unique_ptr<int> p;   // uses default deleter

                              // alpha and beta use independent copies of the deleter:
    std::unique_ptr<int, state_deleter> alpha(new int);
    std::unique_ptr<int, state_deleter> beta(new int, alpha.get_deleter());

    // gamma and delta share the deleter "del" (deleter type is a reference!):
    std::unique_ptr<int, state_deleter&> gamma(new int, del);
    std::unique_ptr<int, state_deleter&> delta(new int, gamma.get_deleter());

    std::cout << "resetting alpha..."; alpha.reset(new int);
    std::cout << "resetting beta..."; beta.reset(new int);
    std::cout << "resetting gamma..."; gamma.reset(new int);
    std::cout << "resetting delta..."; delta.reset(new int);

    return 0;
}

输出: 
resetting alpha…[deleted #1] 
resetting beta…[deleted #1] 
resetting gamma…[deleted #1] 
resetting delta…[deleted #2] 
[deleted #3] 
[deleted #4] 
[deleted #2] 
[deleted #2] 
这里我们重点关注delta,这里使用的是按引用传递。 
还有一个地方需要说明: 
析构的顺序与构造的顺序相反~~

go on:


#include <iostream>
#include <memory>

class state_deleter {  // a deleter class with state
    int count_;
public:
    state_deleter() : count_(0) {}
    template <class T>
    void operator()(T* p) {
        std::cout << "[deleted #" << ++count_ << "]\n";
        delete p;
    }
};

int main() {
    state_deleter del;

    std::unique_ptr<int> p;   // uses default deleter

                              // alpha and beta use independent copies of the deleter:
    std::unique_ptr<int, state_deleter> alpha(new int);
    std::unique_ptr<int, state_deleter> beta(new int, alpha.get_deleter());

    // gamma and delta share the deleter "del" (deleter type is a reference!):
    std::unique_ptr<int, state_deleter&> gamma(new int, del);
    std::unique_ptr<int, state_deleter&> delta(new int, gamma.get_deleter());

    std::cout << "resetting alpha..."; alpha.reset(new int);
    std::cout << "resetting beta..."; beta.reset(new int);
    std::cout << "resetting gamma..."; gamma.reset(new int);
    std::cout << "resetting delta..."; delta.reset(new int);

    //std::cout << "calling gamma/delta deleter...";
    gamma.get_deleter()(new int);

    alpha.get_deleter() = state_deleter(); // a brand new deleter for alpha

                                            // additional deletions when unique_ptr objects reach out of scope
                                            // (in inverse order of declaration)

    return 0;
}

此时输出: 
//输出: 
//resetting alpha…[deleted #1] 
//resetting beta…[deleted #1] 
//resetting gamma…[deleted #1] 
//resetting delta…[deleted #2] 
//calling gamma / delta deleter… 
//[deleted #3] 
//[deleted #4] 
//[deleted #5] 
//[deleted #2] 
//[deleted #1]

最后再来一个:

#include <iostream>  
#include <memory>  

using namespace std;

void deleter(int* ptr) {
    delete ptr;
    ptr = nullptr;
    std::clog << "shared_ptr delete the pointer." << std::endl;
}

int main(void) {

    //定义函数类型  
    typedef void(*tp) (int*);
    typedef decltype (deleter)* dp;
    using up = void(*) (int*);

    std::shared_ptr<int> spi(new int(10), deleter);
    std::shared_ptr<int> spi2(new int, deleter);
    spi2 = std::make_shared<int>(15);

    std::cout << "*spi = " << *spi << std::endl;
    std::cout << "*spi2 = " << *spi2 << std::endl;

    //unique_ptr是模板函数需要删除器(deleter)类型, 再传入具体的删除器  
    std::unique_ptr<int, decltype(deleter)*> upi(new int(20), deleter);
    std::unique_ptr<int, tp> upi2(new int(25), deleter);
    std::unique_ptr<int, dp> upi3(new int(30), deleter);
    std::unique_ptr<int, up> upi4(new int(35), deleter);

    std::cout << "*upi = " << *upi << std::endl;
    std::cout << "*upi2 = " << *upi2 << std::endl;
    std::cout << "*upi3 = " << *upi3 << std::endl;
    std::cout << "*upi4 = " << *upi4 << std::endl;

    return 0;

}
//输出:
//shared_ptr delete the pointer.
//*spi = 10
//* spi2 = 15
//* upi = 20
//* upi2 = 25
//* upi3 = 30
//* upi4 = 35
//shared_ptr delete the pointer.
//shared_ptr delete the pointer.
//shared_ptr delete the pointer.
//shared_ptr delete the pointer.
//shared_ptr delete the pointer.

只是分析这两句:

std::shared_ptr<int> spi2(new int, deleter);
spi2 = std::make_shared<int>(15);

这时候会调用deleter删除器!


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值