使用智能指针
C++有三个智能指针模板(auto_ptr,unique_ptr,shared_ptr),都定义了类似于指针的对象,可以将new获得的地址赋值给这种对象.(其中auto_ptr是C++98提供的解决方案,C++11已经摒弃,不建议使用).当智能指针过期时,其析构函数将使用delete来释放内存.另外share_ptr和unique_ptr的行为与auto_ptr相同.
要使用智能指针首先包含头文件memory.
new double是new返回的指针,指向新分配的内存块.他是构造函数auto_ptr<double>
的参数.即对应于原型中的形参p的实参.同样new double也是构造函数的实参.其他两种智能指针的写法:
下列代码举例了全部三种智能指针:
智能指针很多地方和正常指针类似,可以对他进行解引用操作( *p),用它来访问成员(p->fun),将他赋值给指向相同类型的常规指针,或者赋值给另一个同类型的只能指针;
unique_ptr为何优于auto_ptr
auto:
在第三句,p2接管string对象所有权后,p1的所有权被剥夺,但如果程序随后视图使用p1,则是件坏事因为p1已经不再指向有效的数据;
unique_ptr:
编译器认为第三句非法,避免了p3不再指向有效数据的问题;
但有时候将一个智能指针赋值给另一个不会出现悬挂指针的危险:
demo()返回一个临时unique_ptr,然后ps接管了demo的临时返回值,ps拥有了string对象的所有权.因为demo返回的临时对象很快就会被销毁.所以没有机会使用它来访问无效的数据,所以编译器允许这种赋值.所以就是,如果源unique_ptr是个临时右值,编译器将允许赋值,但如果源unique_ptr将存在一段时间,编译器将禁止这样做..…..
如果一定要写类似于p3p4那样的代码.要安全的使用指针的话,可以给他赋新值,C++有个标准库函数std::move()
,能够让你将一个unique_ptr赋给另一个.:
unique_ptr还可以当数组用:
为啥unique_ptr能知道安全和不安全的用法呢? 因为它使用了C++11的移动构造函数和右值引用….
选择智能指针
如果程序要使用多个指向同一个对象的指针,应选择shared_ptr,必去有个指针数组,并使用一些辅助指针来标示特定的元素(比如最大值最小值);比如两个对象都指向第三个对象的指针; stl容器;这些操作都可以使用shared_ptr;但不能用unique_ptr和auto_ptr;
如果程序不需要多个指向同一个对象的指针,则可以使用unique_ptr.如果函数使用new分配内存并返回指向该内存的指针.则其返回类型声明为unique_ptr是个不错的选择;这样所有权将转让给接受返回值的unique_ptr,而该智能指针将负责调用delete;
其中的push_back()调用没毛病,因为他返回一个临时的unique_ptr对象.另外如果安置而不是按引用给show()传递对象,则for_each()将会非法,因为这将导致使用一个来自vp的非临时unique_ptr初始化pi,前面说过,这是不行的.
在unique_ptr为右值的时候,可将其赋值给shared_ptr,要求和赋值给另一个unique_ptr一样:
模板shared_ptr有个显示构造函数,可将右值的unique_ptr转化为shared_ptr.shared_ptr将接管原来的unique_ptr所有的对象;