前言
大家好,我是雨墨,我深知好记性不如烂笔头的道理,所以在阅读的时候都尽量写读书笔记,方便日后复习,当然笔记并不能代替书籍上的内容。希望我的笔记也能帮助到大家,如果我的笔记有什么问题,欢迎大家给小老弟纠错~
条款十三总结
-
为了防止内存资源的泄漏,也就是防范还没到 delete 那一步的时候程序出现了异常,即当你申请使用 new 动态分配对象时,应该在获取资源的时候将其交给智能指针接管。这样就能保证不会出现内存泄漏的情况。
-
借此机会说一说 auto_ptr 和 unique_ptr 的区别,对于 auto_ptr ,复制动作会使它(被复制物)指向 null ,而 unique_ptr 是使用 release + reset 操作实现的。举例说明
auto_ptr<string> atP1(new string("cpp")); auto_ptr<string> atP2(p1); // 现在 atP2 指向 "cpp",而 atP1 指向 null atP1 = atP2; // 现在 atP1 指向 "cpp",而 atP2 指向 null unique_ptr<string> unqP1(new string("yyds")); unique_ptr<string> unqP2(unqP1.release()); // 现在 unqP1 指向 null ,unqP2 指向 "yyds" unqP1.reset(unqP2.release()); // 将 unqP2 指向 null ,unqP1 指向 "yyds"
条款十四总结
- 对于 RAII (资源取得时便是初始化的时机)对象,也就是条款十三所谈及的对象,复制它必须一并复制它所管理的资源,所以资源的 copying 行为决定 RAII 对象的 copying 行为。如果是 auto_ptr ,那么就是转移底部资源的拥有权。
- 普遍而常见的 RAII class copying 行为是:
- 抑制 copying 行为(将 ctor 以及 copy assignment 放入 private 并只做声明)
- 施行引用计数法,但是对应的 delete 可能会替换成其他的操作
条款十五总结
对于一些需要访问原始资源的 APIs ,我们的资源管理类应该采取:
- 显式转换成原始资源,例如 shared_ptr 的 get() 或是 操作符重载 operator-> || operator* ,或是直接提供一个接口函数 (较安全)
- 隐式转换,隐式地将其转换为原始资源 operator() (对于用户较方便)
条款十六总结
new [] 和 delete [] 一起使用,new 和 delete 一起使用。对于 new vector<string>
,只需用 delete
。最好不要使用 typedef 数组然后再使用 new 。
条款十七总结
对于资源管理类,理应采用智能指针。看下列代码:
processWidget(shared_ptr<Widget>(new Widget), priority());
上述代码可能存在内存泄漏:
- new Widget 一定在 shared_ptr 的构造函数之前执行,但是编译器不能保证 priority() 在 shared_ptr 的构造函数之后执行
- 如果 priority() 出现异常
- new Widget 的资源没有得到释放,造成内存泄漏
改进:
// 采用分离语句
shared_ptr<Widget> pw(new Widget);
processWidget(pw, priority());