关于智能指针的问题,有时候为了方便,需要在析构时附加一些清理操作,或者,有的指针本身来自C的库文件中,这时候,就非常期望能够使用自定义的deleter,
但是标准C++创建函数如std::make_unique / std::make_shared 等不支持创建带有自定义deleter的智能指针,这时,我们只能使用自己的办法,
- #include
- #include
-
- class myclass {
- public:
- myclass() {
- std::cout << "myclass" << std::endl;
- }
-
- ~myclass() {
- std::cout << "~myclass" << std::endl;
- }
-
- void doSomething() {
- std::cout << "myclass is doing something" << std::endl;
- }
- };
-
- class A {
- public:
- A(){
- std::cout << "A" << std::endl;
- }
-
- ~A(){
- std::cout << "~A" << std::endl;
- }
-
- void doSomething() {
- std::cout << "A is doing something" << std::endl;
- }
- };
-
- struct my_creator_s {
- myclass* p = new myclass();
- A* a = new A();
- };
- struct my_deleter_s {
- void operator()(myclass* p) { delete p; }
-
- };
- struct my_deleter_s2 {
- void operator()(my_creator_s* s) { delete s->p; delete s->a; }
- };
-
- myclass* mycreator() {
- return new myclass();
- }
- void mydeleter(myclass* p){
- delete p;
- };
-
- int Test1() {
- std::cout << "----------------------------Test Method 1-----------------------------" << std::endl;
- myclass* myptr = new myclass;
- std::unique_ptr
decltype(&mydeleter)> ptr{ myptr, &mydeleter }; - ptr->doSomething();
- return 0;
- }
-
- int Test2() {
- std::cout << "----------------------------Test Method 2-----------------------------" << std::endl;
- std::unique_ptr
ptr2 = std::unique_ptr(new myclass(), my_deleter_s()); - ptr2.get()->doSomething();
- return 0;
- }
-
- int Test3() {
- std::cout << "----------------------------Test Method 3-----------------------------" << std::endl;
- std::unique_ptr
ptr3 = std::unique_ptr(new my_creator_s(), my_deleter_s2()); - ptr3.get()->a->doSomething();
- return 0;
- }
-
- int main() {
- Test1();
- Test2();
- Test3();
- return 0;
- }
这段代码的输出如下,
----------------------------Test Method 1-----------------------------
myclass
myclass is doing something
~myclass
----------------------------Test Method 2-----------------------------
myclass
myclass is doing something
~myclass
----------------------------Test Method 3-----------------------------
myclass
A
A is doing something
~myclass
~A
说明:这里写了两个creator,函数mycreator没有用到;deleter一个采用了struct的办法,一个是采用了void函数的办法,大家可以自己尝试; 对于需要同时处理多个参数或变量的形式,建议采用struct或class的形式,Test Method3展示了如何使用creator或者说constructor创建的办法,写成这种方式是因为智能指针的deleter中只接受一个参数,例如,不能写成这样的,
- struct my_deleter_s2 {
- void operator()(myclass* p, A* a) { delete p; delete a; }
- };
参考附录:
Custom Deleter for C++ Smart Pointers - Lei Mao's Log Book
本文结束