实战c++中的智能指针unique_ptr系列-- unique_ptr的get_deleter方法(自定义删除器)
2015-12-26 13:08
731 查看
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.
直接看例子:
运行程序,输出结果:
[deleted #1]
[deleted #1]
说明了,在函数结束的时候,alpha beta的析构函数被调用了,而且析构函数是我们自己定义的类。
在上面的代码上加入对alpha beta的操作:
输出:
resetting alpha…[deleted #1]
resetting beta…[deleted #1]
[deleted #2]
[deleted #2]
说明在reset方法后,也调用了自定义的析构~
再继续添加代码:
输出:
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:
此时输出:
//输出:
//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]
最后再来一个:
只是分析这两句:
这时候会调用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删除器!
相关文章推荐
- 实战c++中的智能指针unique_ptr系列-- unique_ptr的get_deleter方法(自定义删除器)
- C++ string的遍历
- C++学习日记2015.12.26
- C++ STL算法
- C语言学习鸡汤
- C++ vector和map的嵌套使用
- C++ 中的const用法整理
- C语言和OC的区别? 面向对象和面向过程的区别?
- C++ 复制控制
- C++指针数组、数组指针、函数指针
- 纠正《Effective C++(第三版)》侯捷译 中文版中,第31条款中原文“最后,不论Handle classes或Interface classes,一旦脱离inline函数都无法...”的误译
- Dijkstra's Shortest Path - C++ for C Programmers 2.5
- c++配置mysql,读取的基本api
- C++连接本地SQL数据库
- Effective C++ 条款24
- libc++abi.dylib: terminate_handler unexpectedly threw an exception
- 程序员之---C语言细节22(函数返回指针注意事项<悬空指针>、查看进程能够分配的内存大小)
- C++ primer (第五版)学习记录1
- 求一个面的法向 c++
- 求矩阵的逆矩阵 c++