练习12.14
编写你自己版本的用shared_ptr管理connection函数。
解答:
个人比较喜欢带有删除器的版本。
练习12.15
重写第一题的程序,用lambda(参见10.3.2节,第346页)代替end_connection函数。
解答:
connection c = connect(&d);
shared_ptr<connection> p(&c, [c](){disconnect(&c);});
练习12.16
如果你试图拷贝或赋值unique_ptr,编译器并不能总是能给出易与理解的错误信息。
编写包含这种错误的程序,观察编译器如何诊断这种错误。
解答:
unique_ptr<string> p1(new string("abc"));
unique_ptr<string> p2(p1);
VS2013上的错误信息
1> 源.cpp
1>源.cpp(67): error C2280: “std::unique_ptr<std::string,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)”: 尝试引用已删除的函数
1> with
1> [
1> _Ty=std::string
1> ]
1> E:\program\Microsoft Visual Studio 12.0\VC\include\memory(1486) : 参见“std::unique_ptr<std::string,std::default_delete<_Ty>>::unique_ptr”的声明
1> with
1> [
1> _Ty=std::string
1> ]
clang3.4给出的错误信息
test.cpp:7:22: error: call to deleted constructor of 'unique_ptr<string>'
unique_ptr<string> p2(p1);
^ ~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/unique_ptr.h:273:7: note: function has been explicitly marked deleted here
unique_ptr(const unique_ptr&) = delete;
^
1 error generated.
test.cpp: In function ‘int main()’:
test.cpp:7:27: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = std::basic_string<char>; _Dp = std::default_delete<std::basic_string<char> >]’
unique_ptr<string> p2(p1);
^
In file included from /usr/include/c++/4.8/memory:81:0,
from test.cpp:1:
/usr/include/c++/4.8/bits/unique_ptr.h:273:7: error: declared here
unique_ptr(const unique_ptr&) = delete;
^
这里“引用已删除的函数”就不是很好理解。
对比三个编译器给出的错误提示,clang的算是比较容易理解的。
它明确的告诉你,在做拷贝之前p1就已经被删除了,所以这里不允许这样拷贝。
练习12.17
下面unique_ptr声明中,哪些是合法的,哪些可能导致后续的程序错误?解释每个错误的问题在哪里。
int ix = 1024, *pi = &ix, *pi2 = new int(2048);
typedef unique_ptr<int> IntP;
(a)IntP p0(ix);
(b)IntP p1(pi);
(c)IntP p2(pi2);
(d)IntP p3(&ix);
(e)IntP p4(new int(2048));
(f)IntP p5(p2.get());
解答:
(a) 非法,不能将int型变量直接拷贝给unique_ptr
(b) 非法,ix是从栈上分配出来的,在程序结束的时候会自行销毁。当放入智能指针后,程序结束时会产生重复释放的问题。(感谢stienian的提醒)
(c) 合法
(d) 非法,原因同(b)
(e) 合法
(f) 非法,会产生二次销毁的错误。
练习12.18
shared_ptr为什么没有release成员?
解答:
在unique_ptr中使用release 是放弃对指针控制权,返回内置指针,并将原unique_ptr置为空。
而shared_ptr中是多个对象共享同一段内存,直接release会造成使用上的问题,会导致其他对象失效,并出现奇怪的错误。