您的位置:首页 > 其它

智能指针作为函数参数:普通参数、指针参数、WPARAM

2013-04-27 14:26 260 查看
一、auto_ptr和shared_ptr作为普通参数、指针参数

我想这是我们使用最多的,直接传过去好了,基本上没什么好担心的。例如:

1.

T* pt = new T;

auto_ptr<T> ap( pt);

// void f1(auto_ptr<T> ap);

f1(ap);

// ap 为 empty(空)了

// void f2(T* pt);

f2(ap.get());

// ap还拥有所有权。

唯一要注意的是,auto_ptr是独占的,一旦赋值给别人后,就把所有权也交给别人了,自己就是一个空指针了,不能再使用了。详细请看stl文档或stl标准程序库。

2.

shared_ptr<T> sp(new T);

// void f1(shared_ptr<T> 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<test> shPtr = shared_from_this();

boost::weak_ptr<test> wPtr=shPtr;

_beginthreadex( NULL, 0, &test::threadRun, &wPtr, 0, &threadID );

...

}

/*this is a static function*/

UINT __stdcall test::threadRun( LPVOID lpParam )

{

shared_ptr<test> k = static_cast< boost::weak_ptr<test>* >(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<T> apMessage(newT());

if (PostMessage(WM_SHOW_MESSAGE, (WPARAM)apMessage.get(), ID_***))

{

// 释放控制权

apMessage.release();

}

接收者:

std::auto_ptr<T> apShowMessage(reinterpret_cast<T*>(wParam));

唯一要注意的是,发送者要释放控制权,不然,接收者无法重新包装成auto_ptr,我刚开始犯过这样的错误。表面上好像成功了,但是由于发送者并没有释放控制权即所有权,所以接收者并不能使用新包装的auto_ptr(表面上可以得到指针,由于异步,发送者并没有转交所有权,PostMessage后就释放内存了,接收者得到的是一个野指针)。

所以需要发送者在发送成功后释放控制权,让接收者重新包装成auto_ptr,得到其所有权。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: