1.考虑这样的processWidget函数声明:
void processWidget(shared_ptr<Widget> pw, int priority);
当我们采取这样的方式调用:
processWidget(new Widget, priority());
显然是不能编译通过的,因为shared_ptr不接受通过new指针隐式的构造(explicit)
所以这样写就能通过编译:
processWidget(shared_ptr<Widget>(new Widget), priority())
此时虽然能够通过编译,但是仍然存在一个隐形的资源泄露问题。因为C++编译器对new Widget, shared_ptr构造函数, priority函数调用这三者次序不定,所以当执行顺序为1>new widget 2>priority() 3>shared_ptr构造函数时,第二步发生异常,那么第一步申请的内存就造成泄露。解决办法是用独立语句来把对象放入智能指针:
shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());
2. 考虑这样的函数声明:
process(shared_ptr<int> ptr);
process函数参数采取值传递方式,因此实参会被拷贝到ptr中。这样在函数运行过程中,引用计数至少为2。当process结束时,ptr引用计数会递减,但不会变为0.因此当局部变量ptr被销毁时,ptr指向的内存不会被释放。
使用此函数的正确方法:
shared_ptr<int> p(new int(42));
process(p);
虽然不能直接传递一个内置指针,但是可以传递一个临时的shared_ptr, 考虑如下调用:
int *x(new int(1024));
process(shared_ptr<int>(x));
结果是经由x指针申请的内存,在process函数处理结束之后被销毁了。但x继续指向已经释放的内存,从而变成一个野指针。当将一个shared_ptr绑定到一个普通指针时,我们就将内存的管理责任交给了这个shared_ptr。一旦这样做了,我们就不应该再使用内置指针来访问shared_ptr所指向的内存了。