智能指针作为函数参数:普通参数、指针参数、WPARAM | 您所在的位置:网站首页 › 智能指针作为参数使用什么 › 智能指针作为函数参数:普通参数、指针参数、WPARAM |
一、auto_ptr和shared_ptr作为普通参数、指针参数 我想这是我们使用最多的,直接传过去好了,基本上没什么好担心的。例如: 1. T* pt = new T; auto_ptr ap( pt); // void f1(auto_ptr ap); f1(ap); // ap 为 empty(空)了
// void f2(T* pt); f2(ap.get()); // ap还拥有所有权。 唯一要注意的是,auto_ptr是独占的,一旦赋值给别人后,就把所有权也交给别人了,自己就是一个空指针了,不能再使用了。详细请看stl文档或stl标准程序库。
2. shared_ptr sp(new T); // void f1(shared_ptr sp); f1(sp); // sp还可以继续使用,引用计数型
// void f2(T* pt); f2(sp.get());
二、关于线程 auto_ptr的拥有权只有一份,所以不适合赋值给多个线程。shared_ptr是线程安全的,没有问题。 如果你用boost里面的线程,用boost::function函数对象用shared_ptr还是很简单的。
如果用_beginthreadex和UINT __stdcall threadRun(LPVOID lpParam),哥求你,放弃这种使用方式吧。我现在很不喜欢这种使用方式,太古板了。如果你要在这种方式下使用智能指针赋值给LPVOID,那使用就稍微麻烦一点。 auto_ptr就不讲了,因为所有权的问题不建议给赋值给线程参数,如果要使用,请借鉴后面赋值给WPARAM。 shared_ptr网上有一个思路是对的,但有严重缺陷的方式:http://stackoverflow.com/questions/5102038/how-can-i-pass-boostshared-ptr-as-a-pointer-to-a-windows-thread-function?rq=1 test::start() { .... shared_ptr shPtr = shared_from_this(); boost::weak_ptr wPtr=shPtr; _beginthreadex( NULL, 0, &test::threadRun, &wPtr, 0, &threadID ); ... } /*this is a static function*/ UINT __stdcall test::threadRun( LPVOID lpParam ) { shared_ptr k = static_cast< boost::weak_ptr* >(lpParam)->lock(); ... } 使用boost::weak_ptr的思路是很正确的,但是这样传&wPtr是很有问题的。必须用其他方式包装或传递shared_ptr。
三、PostMessage中智能指针传给WPARAM 最近一个项目中,要把一个结构通过PostMessage传给界面线程。这个结构数据当然是临时生成的,我这个工作线程对界面线程一无所知,只能通过发消息通知,boost里面的回调函数和信号事件无效。因为有个使用别人的控件窗口只能界面线程调用才显示,我也是用boost里面函数和回调不显示郁闷了很久,后来排除一切不可能因素才认定是工作线程非界面线程原因。 直接使用new是一件很头疼的事,因为释放是一件很麻烦的事,基本上不能遵守谁申请谁释放,因为我只负责把数据产生出来交给调用者,调用者的情况完全不知。 shared_ptr用的多,那就还是用只能指针吧。shared_ptr方式,完全可以参考上面的“二、关于线程”,用boost::weak_ptr辅助。 当然我用了auto_ptr,因为我觉得auto_ptr更符合我这里使用情况,把所有权转交给别人,自己就不管了。而且还不需要辅助指针weak_ptr。 下面介绍使用方式: 发送者: std::auto_ptr apMessage(newT()); if (PostMessage(WM_SHOW_MESSAGE, (WPARAM)apMessage.get(), ID_***)) { // 释放控制权 apMessage.release(); }
接收者: std::auto_ptr apShowMessage(reinterpret_cast(wParam));
唯一要注意的是,发送者要释放控制权,不然,接收者无法重新包装成auto_ptr,我刚开始犯过这样的错误。表面上好像成功了,但是由于发送者并没有释放控制权即所有权,所以接收者并不能使用新包装的auto_ptr(表面上可以得到指针,由于异步,发送者并没有转交所有权,PostMessage后就释放内存了,接收者得到的是一个野指针)。 所以需要发送者在发送成功后释放控制权,让接收者重新包装成auto_ptr,得到其所有权。
|
CopyRight 2018-2019 实验室设备网 版权所有 |