智能指针、左值引用右值引用、lambda表达式

1. 智能指针(shared_ptr、unique_ptr、weak_ptr)

1.1 智能指针用来解决什么问题

 智能指针主要解决以下问题:
   1. 内存泄漏:在堆上申请的内存手动释放(new/malloc),使用智能指针内存可以自动释放。
   2.共享所有权指针的传播和释放:比如多线程用同一个对象的析构问题。
在这里插入图片描述
 智能指针的区别:
   shared_ptr共享对象的所有权,性能越差;
   unique_ptr独享对象所有权,由于没有引用计数,因此性能较好;
   weak_ptr配合shared_ptr,解决循环引用的问题。

1.2 shared_ptr

1.2.1 shared_ptr内存模型

  std::shared_ptr使用引用计数,每一个shared_ptr的拷贝都指向相同的内存。再最后一个shared_ptr析构的时候,内存才会被释放。
  std::shared_ptr内部包含两个指针,一个指向对象,另一个指向控制块(control block),控制块中包含一个引用计数(reference count), 一个弱计数(weak count)和其它一些数据。
  use_count,当前这个堆上对象被多少对象引用了,简单来说就是引用计数。
在这里插入图片描述

1.2.2 shared_ptr的基本用法

·初始化

  1. 初始化make_shared/reset

  1. 通过构造函数,std::shared_ptr辅助函数和reset方法来初始化shared_ptr;
  2. 优先使用make_shared来构造指针指针,因为他更高效。
  3. 不能讲一个原始指针赋值给一个智能指针。
  4. 当智能指针有值时调用reset()会引起引用计数减1.

//shared_ptr的初始化:通过构造函数、make_shared、reset()方法
int main(){
   
	shared_ptr<int> p1(new int(1));	//通过构造函数初始化
	shared_ptr<int> p2 = p1;	//拷贝构造函数
	shared_ptr<int> p3;
	p3.reset(new int(100));		//reset()方法

	shared_ptr<int> p4 = make_shared<int>(100);

	//不能将一个裸指针赋值给一个智能指针
	//shraed_ptr<int> p5 = new int(5);	//错误的

	if(p1){
   
		cout << "p1 use_count():  " << p1.use_count() << endl;	// 2
		p2.reset();		//引用计数-1
		cout << "p1 use_count():  " << p1.use_count() << endl;	// 1
	}
	return 0;
	
}

  1. 获取原始指针get
	//使用get()方法获取裸指针p,delete p会导致裸指针被释放两次
	{
   
		shared_ptr<int> ptr = make_shared<int>(100);
		int *p = ptr.get();				
		//delete p;					//double free or corruption (out)
	}
  1. 指定删除器
int main(){
   

	//如果使用shared_ptr管理非new对象或者是没有析构函数的类时,应当为其传递合适的删除器
	shared_ptr<int> p1(new int(10), DeleteIntPtr);

	//删除器可以是一个lambda表达式
	shared_ptr<int> p2(new int(20), [](int *p)->void{
   
		cout << "call lambda delete p" << endl;
		delete p;
	});

	//当我们使用shared_ptr管理动态数组时,需要指定删除器,因为shared_ptr的默认删除器不支持对数组对象。
	shared_ptr<int> p3(new int[10], [](int *p){
   
		cout << "call lambda delete p[]" << endl;
		delete []p;
	});
	
}

1.2.3 使用shared_ptr要注意的问题

  1. 不要使用一个原始指针初始化多个shared_ptr,会出现同一个资源被多次释放的错误。
  2. 不要在函数实参中创建shared_ptr,不同编译器函数的参数计算顺序是不是一样的,可能会存在已经new创建的对象资源,由于异常shared_ptr智能指针还来不及创建,出现内存泄漏。
  3. 通过shared_from_this()返回this指针,this指针本身就是一个裸指针,函数返回shared_ptr的this指针,为其他的shared_ptr指针初始化,其本质相当于使用同一个原始指针初始化多个shared_ptr,会导致资源被释放多次。
  4. 避免循环引用,循环引用导致智能指针的引用计数为2,但是离开作用域之后智能指针的引用计数减为1,并没有减为0,导致两个指针都不会被析构,造成内存泄漏。
    解决的办法是把A和B任何一个成员变量改为weak_ptr
class A;
class B;

class A {
   
public:
    std::shared_ptr<B> bptr;
    ~A() {
   
        cout << "A is deleted" << endl;
    }
};

class B {
   
public:
    std::shared_ptr<A> aptr;
    ~B() {
   
        cout << "B is dele
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值