虽然久闻C++标准库的auto_ptr“带来的问题比解决的问题多”,但以为自己有足够的知识和心理准备,完全能够应付auto_ptr的古怪特性,没想到今天还是在这里栽跟头了。我原以为auto_ptr最多就是ownership问题,只要我不传递ownership,就不会出错,于是就在函数中将auto_ptr用于动态对象的自动析构。
ISocket
*
new_server_db();
auto_ptr < ISocket > s = new_udp_socket();
s -> open(PORT);
auto_ptr < ISocket > s = new_udp_socket();
s -> open(PORT);
在编译连接正确之后,没想到这样的代码竟然竟然应藏着运行错误,调用open函数的时候发生异常。经过跟踪发现,new_udp_socket()执行正确;但奇怪的是watch显示不出s里面包含的指针指向的对象信息,我原以为VC05的RTTI没有打开,但在查看工程设置后否定了这个想法;经过step into发现auto_ptr构造似乎也没错误,毕竟只有简单的一个赋值。至此问题一筹莫展。
后来,我抱着试试看的想法,把初始化代码修改成了
auto_ptr
<
ISocket
>
s(new_udp_socket());
竟然运行正确!
直觉告诉我这非常奇怪,于是搜索了这个问题。原来,标准规定auto_ptr的构造函数使用explicit修饰,以使“=”的初始化是不行的,即产生编译错误,必须用括号的初始化,让程序员清楚这不是普通的指针;但是VC在库里做了点“手脚”试图允许“=”的初始化方法,只不过似乎做的不好,反而造成了运行时错误。我的环境是VC2005。