C++:资源管理

文章目录

  • 13:以对象管理资源
  • 14:在资源管理类中小心copying行为
  • 15:在资源管理类中提供对原始资源的访问
  • 16:成对使用new和delete时要采取相同形式
  • 17:以独立语句将newed对象置入智能指针

本章主要总结的是,在C++中对于资源管理提供的一些方法

13:以对象管理资源

给出下面的使用场景

class A
{
public:
	A()
		:pa(new int(0))
	{
		cout << "调用构造函数" << endl;
	}
	~A()
	{
		delete pa;
		cout << "调用析构函数" << endl;
	}
private:
	int* pa = nullptr;
};

A* create()
{
	A* pa = new A;
	cout << "申请A空间成功" << endl;
	return pa;
}

void func()
{
	A* pa = create();
	cout << endl << "完成一些必要步骤..." << endl << endl;
	delete pa;
}

int main()
{
	func();
	return 0;
}

这个使用场景在正常看来是没有任何问题的,但是对于func函数,如果在这段完成一些必要步骤…这段时间内出现了意外情况,例如抛出异常等等,导致程序未能运行到delete部分,那么就会导致内存泄漏,例如如下场景

void func()
{
	A* pa = create();
	cout << endl << "完成一些必要步骤..." << endl << endl;
	throw -1;
	delete pa;
}

C++:资源管理_第1张图片
那么在这样的场景下,就会发生内存泄漏,那么如何解决这样的场景?有没有一个合适的方法呢?答案是有的,就是用对象管理资源,具体的实现原理如下所示

class A
{
public:
	A()
		:pa(new int(0))
	{
		cout << "调用构造函数" << endl;
	}
	~A()
	{
		delete pa;
		cout << "调用析构函数" << endl;
	}
private:
	int* pa = nullptr;
};

class B
{
public:
private:
	A a;
};

void func()
{
	B b;
	cout << endl << "完成一些必要步骤..." << endl << endl;
	throw - 1;
}

//void func()
//{
//	A* pa = create();
//	cout << endl << "完成一些必要步骤..." << endl << endl;
//	throw -1;
//	delete pa;
//}

int main()
{
	try
	{
		func();
	}
	catch(...)
	{ }
	return 0;
}

这样的情况下,即使确实是抛出异常或由于其他原因发生了终止,但是依旧会正常释放,这就是用对象来管理资源的好处,因为当离开了对象所在的作用域后,它会自发的调用析构函数来结束自己的生命,那么基于这个原理,就可以设计出这样的模式

其实这样的模式也并不陌生,智能指针就是一个最好的样例,智能指针可以很好的解释这个过程,因此这里不再过多赘述,理解为什么要用对象管理资源,以及对象管理资源的好处是核心所在

14:在资源管理类中小心copying行为

对于这个条款其实也很好理解,有了前面智能指针的基础,想要突出的重点就是,在用资源管理类时,如果遇到复制的行为,要小心过多析构导致崩溃的问题,要不然选择禁止拷贝,要不然选择引用计数的方法来解决再或者是采用转移对象资源等等其他方法来解决问题都可以

复制RAII对象必须一并复制它所管理的资源,所以资源的copying行为决定了RAII对象的copying行为
普遍而常见的RAII class copying行为是,抑制copying、施行引用计数。不过其他行为也都可能被实现

15:在资源管理类中提供对原始资源的访问

这个也比较好理解,用对象管理资源,这个对象必须要提供资源的访问方式

APIs往往要求访问原始资源,所以每一个RAII class应该提供一个“取得其所管理之资源”的方法
对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全,但隐式转换对客户比较方便

16:成对使用new和delete时要采取相同形式

这个也比较好理解,new和delete要配套使用

如果你在new表达式中使用[],必须在相应的delete表达式中也使用[]。如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[]

17:以独立语句将newed对象置入智能指针

本条款强调的核心点是,new对象返回的指针必须有确切的变量接收,再由这个确切的变量传参到指定的函数,否则造成的后果可能有内存泄漏问题,因为在new对象返回的指针到智能指针构造这段过程中,可能会因为异常导致构造中断,造成的后果就是new对象返回的指针没有一个保存的值,使得这个指针被内存泄漏

以独立语句将newd对象存储到智能指针内。如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄露

你可能感兴趣的:(C++,书籍笔记,c++)