c++11新特性之智能指针std::shared_ptr、std::weak_ptr、std::unique_ptr的使用

c++11新特性之智能指针std::shared_ptr、std::weak_ptr、std::unique_ptr的使用

文章目录

  • c++11新特性之智能指针std::shared_ptr、std::weak_ptr、std::unique_ptr的使用
  • 结论
  • 示例
  • 参考


结论

1.std::shared_ptr是共享内存的指针,std::unique_ptr是不用自己管理内存的指针,std::weak_ptr用来监视 std::shared_ptr的生命周期,它的拷贝的析构都不会影响引用计数
2.std::weak_ptr可以解决循环引用问题,std::unique_ptr不允许拷贝和赋值
3.原始指针和智能指针不推荐混用


示例

#include 
#include 

struct ClassWrapper
{
	ClassWrapper() { 
		std::cout << "construct" << std::endl; 
		data = new int[10];
	}

	ClassWrapper(int num) : m_num(num) {
		std::cout << "construct" << std::endl;
		data = new int[10];
	}

	~ClassWrapper() { 
		std::cout << "deconstruct" << std::endl;
		if (data != nullptr) { 
			delete[] data; 
		} 
	}
	void Print() { 
		std::cout << "print" << std::endl; 
	}
	int* data;
	int m_num;
};

class This :public std::enable_shared_from_this<This>
{
public:
	This(){ }
	std::shared_ptr<This> getShaderdThis(){
		return shared_from_this(); //通过weak_ptr 返回的 this 指针
		// return shared_ptr(this); 错误,会导致 double free
	}
};

struct A;
struct B;

struct A { 
	std::shared_ptr<B> bptr; 
	~A() { 
		std::cout << "A delete" << std::endl; 
	}
	void Print() { 
		std::cout << "A" << std::endl;
	} 
}; 

struct B {
	//std::shared_ptr aptr; 这个会出现循环引用问题
	std::weak_ptr<A> aptr; // 这里改成 weak_ptr 
	~B() { 
		std::cout << "B delete" << std::endl;
	}
	void PrintA() { 
		if (!aptr.expired()) { // 监视 shared_ptr 的生命周期 
			auto ptr = aptr.lock(); 
			ptr->Print();
		}
	} 
};


void Func(std::shared_ptr<ClassWrapper> ptr) { 
	ptr->Print(); 
	std::cout << ptr.use_count() << std::endl;
	ptr->Print();
}


int main() {

//一、初始化
	//普通
	int* int_ptr = new int(10);
	std::shared_ptr<int> int_smart_ptr = std::make_shared<int>(10);
	std::unique_ptr<int> int_unique_ptr = std::make_unique<int>(10);

	//数组
	int* int_array_ptr = new int[10];
	std::shared_ptr<int[]> int_array_smart_ptr(new int[10]);
	//c++20才支持:std::shared_ptr int_array_smart_ptr2 = std::make_shared(100);
	std::unique_ptr<int[]> int_array_unique_ptr(new int[10]);
	std::unique_ptr<int[]> int_array_unique_ptr2 = std::make_unique<int[]>(100);

	//类
	ClassWrapper* class_ptr = new ClassWrapper;
	ClassWrapper* class_ptr2 = new ClassWrapper(10);
	std::shared_ptr<ClassWrapper> class_smart_ptr = std::make_shared<ClassWrapper>();
	std::shared_ptr<ClassWrapper> class_smart_ptr2 = std::make_shared<ClassWrapper>(10);
	std::unique_ptr<ClassWrapper> class_unique_ptr = std::make_unique<ClassWrapper>();
	std::unique_ptr<ClassWrapper> class_unique_ptr2 = std::make_unique<ClassWrapper>(10);

//二、查看shared_ptr内存共享情况和引用计数
	//1.数组?
	//非数组
	std::shared_ptr<ClassWrapper> class_smart_ptr_count1 = class_smart_ptr;
	std::cout << class_smart_ptr.use_count() << std::endl;
	std::cout << class_smart_ptr_count1.use_count() << std::endl;
	std::shared_ptr<ClassWrapper> class_smart_ptr_count2 = class_smart_ptr_count1;
	std::cout << class_smart_ptr.use_count() << std::endl;
	std::cout << class_smart_ptr_count1.use_count() << std::endl;
	std::cout << class_smart_ptr_count2.use_count() << std::endl;
	//数组
	std::shared_ptr<int[]> int_array_smart_ptr_count1 = int_array_smart_ptr;
	std::cout << int_array_smart_ptr.use_count() << std::endl;
	std::cout << int_array_smart_ptr_count1.use_count() << std::endl;
	std::shared_ptr<int[]> int_array_smart_ptr_count2 = int_array_smart_ptr_count1;
	std::cout << int_array_smart_ptr.use_count() << std::endl;
	std::cout << int_array_smart_ptr_count1.use_count() << std::endl;
	std::cout << int_array_smart_ptr_count2.use_count() << std::endl;
	//结论:数组和非数组一样

	//2.传参计数
	std::cout << "----------------------传参计数-----------------------" << std::endl;
	Func(class_smart_ptr);
	std::cout << class_smart_ptr.use_count() << std::endl;
	std::cout << class_smart_ptr_count1.use_count() << std::endl;
	std::cout << class_smart_ptr_count2.use_count() << std::endl;
	std::cout << "----------------------传参计数-----------------------\n" << std::endl;
	//结论:进入函数时计数+1,退出后-1

//三、相关操作
	//1.获取裸指针
	ClassWrapper *p = class_smart_ptr.get();
	p = nullptr;

	//2.std::unique_ptr 是 move-only 的
	std::unique_ptr<ClassWrapper> class_unique_ptr_right = std::move(class_unique_ptr); //right
	//std::unique_ptr class_unique_ptr_error = class_unique_ptr;  // 编译错误

	//3.通过 shared_from_this()返回 this 指针
	std::cout << "\n----------------------通过 shared_from_this()返回 this 指针-----------------------" << std::endl;
	std::shared_ptr<This> get_this_smart_ptr = std::make_shared<This>();
	std::shared_ptr<This> p1 = get_this_smart_ptr->getShaderdThis();
	std::cout << get_this_smart_ptr.use_count() << std::endl;
	std::cout << get_this_smart_ptr.use_count() << std::endl;
	std::cout << "----------------------通过 shared_from_this()返回 this 指针-----------------------\n" << std::endl;

	//4.通过std::weak_ptr解决循环引用问题
	std::cout << "\n----------------------通过std::weak_ptr解决循环引用问题-----------------------" << std::endl;
	std::shared_ptr<A> aaptr = std::make_shared<A>(); 
	std::shared_ptr<B> bbptr = std::make_shared<B>();
	aaptr->bptr = bbptr; 
	bbptr->aptr = aaptr; 
	bbptr->PrintA();
	std::cout << "----------------------通过std::weak_ptr解决循环引用问题-----------------------\n" << std::endl;

	//5.

	//手动释放内存
	delete int_ptr;
	delete[] int_array_ptr;
	delete class_ptr;
	delete class_ptr2;
	int_ptr = nullptr;
	int_array_ptr = nullptr;
	class_ptr = nullptr;
	class_ptr2 = nullptr;

	return 0;
}

参考

https://zhuanlan.zhihu.com/p/436290273
https://www.zhihu.com/question/400093693/answer/1270543164

你可能感兴趣的:(C++,c++)