EffectiveCpp0x3
[toc]
Resource Management
- 如内存,互斥锁,数据库连接,网络sockets……
- 重要的是,当你不再使用它了,应该将它还给系统。
13. Use objects to manage resources.
获得资源后立刻放进
管理对象(managing object)
内。“资源取得时机便是初始化时机” (Resource Acquisition Is Initialization;RAII
) 。管理对象(managing object) 运用
析构函数
确保资源被释放。
为什么手动释放堆内存容易出错?
e.g:
Investment * createlnvestment();
void f ()
{
Investment* plnv = createlnvestment();……
delete plnv;
return;
}
//若……中有return导致提前返回,则会导致资源泄露,且不易察觉
std::auto_ptr
:已被弃用。由于其拷贝时原先的指针会指向null,致潜在的资源泄漏和行为不确定性。auto_ptr
被 C++11 中引入的unique_ptr
所替代。
1 |
|
- “引用计数智能指针”(Reference Counted Smart Pointer),即
std::shared_ptr
,现已加入std标准库豪华套餐!环状引用问题
可用weak_ptr
解决
1 |
|
请记住
- 防止资源泄漏,请使用
RAII对象
,它们在构造函数中获得资源并在析构函数中释放资源。 - 两个常被使用的
RAII classes
分别是std::shared _ptr
和unique_ptr
。前者通常是较佳选择,因为其copy 行为比较直观。
14. Think carefully about copying behavior in resource-managing classes
对于RAII
对象的复制,我们在大多数时候有一下两种可能:
- 禁止复制,如数据库连接具有
唯一性
的特性,类中堆内存可能因执行多次delete
导致程序发生不明确行为。 - 对底层资源祭出
“引用计数法”
若当引用次数为0
时,我们还想要做其他行为。那么则可以为shared_ptr
指定“删除器”
。
1 |
|
请记住
- 复制RAII 对象必须一并复制它所管理的资源,所以资源的copying 行为决定RAII 对象的copying 行为
- 普遍而常见的RAII class copying 行为是:
抑制copying
、施行引用计数法(reference counting)
。不过其他行为也都可能被实现。
15. Provide access to raw resources in resource-managing classes
//TODO
请记住
16. Use the same form in corresponding uses of new and delete
new
和delete
实际是由operator new
和operator delete
函数实现的。- 如果你在new 表达式中使用[],必须在相应的delete 表达式中也使用[]。如果你在new 表达式中不使用[],一定不要在相应的delete 表达式中使用[]。
内存布局:
我们最好尽量不要对数组形式做typedef
或define
动作,而是采用vector
等templates
代替它:
1 |
|
typedef
和define
的区别:
typedef
是C++的关键字,用于为现有的类型定义一个新的名称(别名)。它在编译时处理,由编译器解释和应用。typedef
只能用于类型的别名,不能用于定义常量或宏函数。
#define
是C和C++中的预处理指令,用于定义宏。它在预处理阶段处理,即在编译之前,文本替换就已经发生了。#define
可以用来定义常量、宏函数,或者类型的别名,
请记住
- 如果你在new 表达式中使用[],必须在相应的delete 表达式中也使用[]。如果你在new 表达式中不使用[],一定不要在相应的delete 表达式中使用[]。
17. Store newed objects in smart pointers in standalone statements
- 其实就是
C++的编译器
可以对参数的执行顺序
进行改变——进行程序优化。Java
和C#
则会按照特定次序完成函数参数的核算。
1 | int priority() ; //优先级函数,构造函数是个explicit构造函数 |
- 以上之所以行得通,因为编译器对于“跨越语句的各项操作“没有重新排列的自由(只有在语句内它才拥有那个自由度)。
请记住
- 以独立语句将newed 对象存储千(置入)智能指针内。如果不这样做,一旦异常被抛出,有可能导致难以察觉的资源泄漏。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Randolfluo's blog!