C++ 智能指针学习

在使用PCL库做点云处理的时候,经常用到了智能指针。智能指针比较常见并且很重要,准备一边学习一边记录一下。

C++没有内存回收机制,new出来的对象需要手动delete,否则会造成内存泄漏。C++引入了智能指针,用于动态资源管理。使用智能指针能够写出异常安全的代码。当对象退出作用域时,智能指针能够自动调用对象的析构函数,从而避免内存泄漏。

每个shared_ptr对象在内部维护着两个内存位置:
1.指向对象的指针;
2.用于控制引用计数数据的指针。
在使用智能指针的过程中,需要避免循环引用,shared_ptr的一个最大的陷进就是循环引用。循环引用会导致堆内存无法正确释放。

与普通指针相比,shared_ptr仅提供->,*和==运算符,没有+,-,++,–和[]等运算符。
当我们创建shared_ptr对象而不分配任何值时,它就是空的。普通指针不分配空间的时候相当于一个野指针,指向垃圾空间,且无法判断指向的是否是有用的数据。

不要使用同一个原始指针构造share_ptr,否则会崩溃。
创建多个shared_ptr的正常方法是使用一个已存在的shared_ptr进行创建,而不是使用同一个原始指针进行创建。
实例:使用 C++11 智能指针时要避开的 10 大错误

int main()

{
    
    

	Aircraft* myAircraft = new Aircraft("F-16");
	
	shared_ptr pAircraft(myAircraft);
	
	cout << pAircraft.use_count() << endl; // ref-count is 1
	
	shared_ptr pAircraft2(myAircraft);
	
	cout << pAircraft2.use_count() << endl; // ref-count is 1
	
	return 0;

}

这将会造成ACCESS VIOLATION(译者注:非法访问)并导致程序崩溃!!!

这样做的问题是当第一个shared_ptr超出作用域时,myAircraft对象就会被销毁,当第二个shared_ptr超出作用域时,程序就会再次尝试销毁这个已经被销毁了的对象!

使用了动态生存期的资源类,程序使用动态内存处于以下三种原因:
1.程序不知道自己需要使用多少对象(容器类);
2.程序不知道所需对象的准确类型;
3.程序需要在多个对象间共享数据。

智能指针是利用了一种叫做RAII(资源获取初始化)的技术对普通的指针进行封装,这使得智能指针实质是一个对象,行为表现的却像一个指针。

unique_ptr 独占指针
在任何给定的时刻,只能有一个指针管理内存。当指针超出作用域时,内存将自动释放。
该类型指针不可copy,只可以move。

三种创建方式:
1.通过已有的裸指针(raw pointer,原始指针)创建;
2.通过new创建;
3.通过std::make_unique创建。
使用方式1的时候,裸指针应该立即被赋给智能指针,而且裸指针不应该被再次调用。创建完独占指针之后,可以delete 裸指针。
使用方式2的时候,会发生两次动态申请内存,一次是new本身申请的对象,另一次是智能指针构造函数引发的资源管理对象分配。

unique_ptr可以通过get()获取地址
unique_ptr实现了->和*
1.可以通过->调用成员函数;
2.可以通过星号来解引用 dereferencing。

函数调用与unique_ptr注意事项
1.Passing by value 值传递
需要用std::move来转移内存拥有权;
如果参数直接传入std::make_unique语句 自动转换为move
2.Passing by reference 引用传递
如果设置参数const则不能改变指向
reset()方法为智能指针清空方法
3.return by value 值返回
指向一个local object
可以用作链式函数

智能指针比较不错的视频教程-原子之音

猜你喜欢

转载自blog.csdn.net/dyk4ever/article/details/126735220