C++11补充:智能指针如std::unique_ptr如何添加自定义的deleter

关于智能指针的问题,有时候为了方便,需要在析构时附加一些清理操作,或者,有的指针本身来自C的库文件中,这时候,就非常期望能够使用自定义的deleter,

但是标准C++创建函数如std::make_unique / std::make_shared 等不支持创建带有自定义deleter的智能指针,这时,我们只能使用自己的办法,

cpp 复制代码
#include <memory>
#include <iostream>

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<myclass, decltype(&mydeleter)> ptr{ myptr,  &mydeleter };
	ptr->doSomething();
	return 0;
}

int Test2() {
	std::cout << "----------------------------Test Method 2-----------------------------" << std::endl;
	std::unique_ptr<myclass, my_deleter_s> ptr2 = std::unique_ptr<myclass, my_deleter_s>(new myclass(), my_deleter_s());
	ptr2.get()->doSomething();
	return 0;
}

int Test3() {
	std::cout << "----------------------------Test Method 3-----------------------------" << std::endl;
	std::unique_ptr<my_creator_s, my_deleter_s2> ptr3 = std::unique_ptr<my_creator_s, my_deleter_s2>(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中只接受一个参数,例如,不能写成这样的,

cpp 复制代码
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

本文结束

相关推荐
CoderCodingNo7 分钟前
【GESP】C++二级真题 luogu-b3924, [GESP202312 二级] 小杨的H字矩阵
java·c++·矩阵
奔跑吧邓邓子32 分钟前
【Python爬虫(34)】Python多进程编程:开启高效并行世界的钥匙
开发语言·爬虫·python·多进程
刃神太酷啦1 小时前
堆和priority_queue
数据结构·c++·蓝桥杯c++组
Heris991 小时前
2.22 c++练习【operator运算符重载、封装消息队列、封装信号灯集】
开发语言·c++
----云烟----1 小时前
C/C++ 中 volatile 关键字详解
c语言·开发语言·c++
yuanpan1 小时前
23种设计模式之《组合模式(Composite)》在c#中的应用及理解
开发语言·设计模式·c#·组合模式
BanLul1 小时前
进程与线程 (三)——线程间通信
c语言·开发语言·算法
十八朵郁金香2 小时前
【JavaScript】深入理解模块化
开发语言·javascript·ecmascript
Hello.Reader2 小时前
深入理解 Rust 的 `Rc<T>`:实现多所有权的智能指针
开发语言·后端·rust
程序员阿鹏2 小时前
jdbc批量插入数据到MySQL
java·开发语言·数据库·mysql·intellij-idea