STL: 弱回调+多线程下内存轻泄漏处理.

#include <map>
#include <cassert>
#include <mutex>
#include < string>
#include <memory>  
#include <iostream> 
#include <type_traits>
#include <functional>


struct Stock
{
	std::string name{ "none" };
	int code{ 0 };

	Stock() = default;
	~Stock() = default;

	Stock(const std::string& the_name)
		:name{ the_name } {}

	Stock(const Stock& other)
		:name{ other.name } {}

	Stock& operator=(const Stock& other)
	{
		this->name = other.name;
		this->code = other.code;
		return (*this);
	}
};


class StockFactory : public std::enable_shared_from_this<StockFactory>
{
public:
	StockFactory() = default;

	~StockFactory()
	{
		std::cout << "destroy the factory!" << std::endl;
	}

	StockFactory(const StockFactory& other) = delete; //!
	StockFactory& operator=(const StockFactory& other) = delete;//!

	std::shared_ptr<Stock> get()const noexcept = delete;  //const value can not invoke
	std::shared_ptr<Stock> get(const std::string& key)noexcept //通过key获取对应的value
	{
		std::shared_ptr<Stock> temp_stock{ nullptr };


		std::lock_guard<std::mutex> lock_guard(this->mutex); //lock
		std::weak_ptr<Stock>& temp_weak = (this->stocks)[key];  //查找map中是否含有该key对应的value.

		temp_stock = temp_weak.lock();

		// != true
		if (!temp_stock)  //如果temp_stock为nullptr那么插入数据到该value中.
		{
			temp_stock.reset(new Stock{ key },
				std::bind(&StockFactory::weak_deleter_call_back,   //这里我们设置了自定义的deleter,保证当该stock没有引用对象的时候能够从map中被移除掉.
					std::weak_ptr<StockFactory>{this->shared_from_this()}, std::placeholders::_1));

			temp_weak = temp_stock;
		}

		return temp_stock;
	}



private:

	static void weak_deleter_call_back(const std::weak_ptr<StockFactory>& weak_ptr, 
		                                                 Stock* stock)noexcept
	{
		std::shared_ptr<StockFactory> temp_factory{weak_ptr.lock()};
		if (temp_factory) // == true
		{
			std::cout << "destroy: " << stock->name << std::endl;
			temp_factory->remove_stcock(stock);
		}

		delete stock;
		stock = nullptr;
	}

	void remove_stock(Stock* stock)const noexcept = delete;
	void remove_stcock(Stock* stock)noexcept
	{
		if (stock != nullptr)
		{
			std::lock_guard<std::mutex> lock_guard{ this->mutex };
			(this->stocks).erase(stock->name);
		}
	}


	mutable std::mutex  mutex{};  
	std::map<std::string, std::weak_ptr<Stock>> stocks{};
};



int main()
{

	//case 1:
	//std::shared_ptr<StockFactory> shared_factory{ std::make_shared<StockFactory>() };
	//{
	//	std::shared_ptr<Stock> temp_stock1{ shared_factory->get("shihua") };
	//	std::cout << temp_stock1.use_count() << "-------------" << std::endl;
	//	std::shared_ptr<Stock> temp_stock2{ shared_factory->get("shihua") };
	//	std::cout << temp_stock2.use_count() << "-------------" << std::endl;
	//}


	std::cout << std::endl;

	//case 2:
	std::shared_ptr<Stock> shared_stock{ nullptr };
	{
		std::shared_ptr<StockFactory> temp_factory{ std::make_shared<StockFactory>() };
		shared_stock = temp_factory->get("shihua");
		std::shared_ptr<Stock> shared_stock2{temp_factory->get("shihua")};
		assert(shared_stock == shared_stock2);
	}



	return 0;
}

 

转载于:https://my.oschina.net/SHIHUAMarryMe/blog/894146

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值