请教关于 std::tr1:function 自动释放问题?

clxye314 2013-01-22 03:23:24
我在项目中使用了 std::tr1:function,发现,如果这个 function 对象中指定的 对象无效了,则 function 在析构时就会崩溃。


void CDlgMapFind::SearchGeomotry( LPCTSTR lpszGeometry )
{
function<void(SEARCHPROGRESS)> callback = bind(&CDlgMapFind::ProcessCallBack, this, placeholders::_1);
m_pMapHelper->StartSearchFeatures( lpszGeometry, m_vecChecks, callback );
}

void CMapHelperBase::StartSearchFeatures( LPCTSTR featureName, const std::vector<int> &vecLayers, std::function<void(SEARCHPROGRESS&)> callback )
{
m_searchParam.featureName = featureName;
m_searchParam.vecLayers = vecLayers;
m_searchParam.callback = callback;

m_thSearchFeatures.SetThreadProc( bind(&CMapHelperBase::SearchFeatures, this, _1, _2), NULL );
m_thSearchFeatures.Start();
}

void CThread::SetThreadProc( std::function<unsigned (CThread*, void*)> funThread, LPVOID lpParam )
{
m_funThread = funThread;
m_pParam = lpParam;
}


m_searchParam.callback 保存了 CDlgMapFind 对象的 SearchGeomotry 函数地址
m_funThread 保存了 CMapHelperBase 对象的 SearchFeatures 函数地址

当 CDlgMapFind 对象先于 CMapHelperBase 对象之前析构时,这时 m_searchParam.callback 在析构时就会崩溃,原因好像是它会 delete 创建的函数对象,而此时 CDlgMapFind 对象已不存在,因此崩溃了。
CThread::m_funThread 也是会发生类似的问题。

我目前采用的办法是在必须对象被删除前手动对 function 置空。但这种方式不够通用,而且当 function 用的比较多的时候必然会差生因疏忽而导致的崩溃现象。

请问,当 function 对象析构时,有没有办法不调用它的删除操作。或者大家有没有其它更好的办法解决这个问题?

谢谢!!
...全文
242 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
taodm 2013-01-30
  • 打赏
  • 举报
回复
我认为,楼主必然是崩溃原因找错了,应该是CDlgMapFind 对象析构后,你还在调用这个functor。
youyou1912 2013-01-30
  • 打赏
  • 举报
回复
1. 从设计角度, CMapHelperBase 提供了注册callback的方法,也应该提供注销callback的方法, 而侦听者CDlgMapFind对象注册了callback, 析构的时候也应该相应的注销它曾经注册的callback. 这样就不会发生生命周期依赖的问题. 所以楼主析构前, 注销还是制空都是合理的. 也应该作为使用规则. 2. 代码方面, 我用vs2012(C++11已经包括tr1), 没有这个问题. 代码如下:

namespace test8 
{
	//http://bbs.csdn.net/topics/390353882
	struct Observee
	{
		void Register(std::function<void(int)> callback)
		{
			callback_ = callback;
		}
		std::function<void(int)> callback_;
	};
	struct Observer
	{
		void ProcessCallBack(int){}
		void DoRegister(Observee* ob)
		{
			function<void(int)> callback = bind1st(mem_fun(&Observer::ProcessCallBack), this);
			ob->Register(callback);
		}
	};

	void test()
	{
		Observee* ob = new Observee;
		Observer* c1 = new Observer;
		c1->DoRegister(ob);
		delete c1;
		delete ob;
	}
}

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧