C++智能指针原理.pdf
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
C++智能指针原理 C++智能指针 1. 智能指针原理 采⽤C++ Primer Plus中作者引出智能指针的⽅式进⾏说明,感觉超好。 ⾸先看2个函数: //函数1 void remodel(std::string & str) { std::string * ps = new std::string(str); ... str = ps; return; } //函数2 void remodel(std::string &str) { std::string * ps = new std::string(str); ... if (weird_thing()) throw exception(); str = *ps; delete ps; return; } 上⾯,函数1每次调⽤都在堆中申请内存,但从未收回,铁定内存泄漏;函数2虽然使⽤了异常,但是代码中出现异常时,delete将不执 ⾏,因此也仍会导致内存泄漏。 分析⼀下问题在哪? 其实不论上⾯remodel()函数是正常终⽌还是异常终⽌的,函数中的指针变量ps⾃⼰占据的内存都将从栈内存中删除,⽽ps指向的新申请到 的堆内存却没有被释放,导致了内存泄漏。所以啊,我们就在想当指针ps⾃⼰占据的内存被释放的时候,它指向的内存也被释放该多好啊。 但问题是ps现在是⼀个常规指针,它⽆法做到这⼀点。那C++中我们想的这件事情谁能帮我们做到呢?那就是类对象的析构函数,当ps是 ⼀个类对象的时候,在ps过期时,它的析构函数释放掉它所指的内存不就完成我们上⾯想要的事情了嘛!这正是C++智能指针的原理!! 这个原理就是:⽤具有析构函数的类对象充当指针,当该指针过期时,它的析构函数释放掉它所指的堆内存。 2. C++中4种智能指针模版类的区别 C++中4种智能指针模版类:auto_ptr,unique_ptr,shared_ptr,weak_ptr。 这4种智能指针也全都是基于上⾯的原理实现的。当使⽤这些指针时,是不需要我们⼿动使⽤delete去释放指针所指内存的。 简单的使⽤实例:记得包含头⽂件memory #include <memory> void remodel(std::string &str) { std::string * ps = new std::string(str); str = *ps; return; } 接下来思考⼀个问题,如果你基于上⾯智能指针的思想实现了⼀个智能指针模版类mysmart_ptr。假设使⽤它进⾏内存管理,看下⾯的赋 值语句: mysmart_ptr<string> ps (new string("I reigned lonely as a cloud.")); mysmart_ptr<string> vocation; vocation = ps; 上⾯ps和vocation将指向同⼀个string对象,这样的话,当程序结束时可能会出现删除同⼀个对象两次的现象——⼀次是ps过期时,另⼀ 次是vocation过期的时候,如果想避免这样的问题的话,我们需要想⼀下怎么解决?其实这样的⽅法有多种: 1. 定义赋值运算符,使之执⾏深拷贝。这样两个指针将指向不同的对象,其中的⼀个对象是另⼀个对象的副本。 2. 建⽴所有权(ownership)概念,对于特定的对象,只能有⼀个智能指针可拥有它,这样只有拥有对象的智能指针的构造函数会删除该 对象。然后,让赋值操作转让所有权。这就是⽤于auto_ptr和unique_ptr的策略,但unique_ptr的策略更严格。 3. 创建智能指针更⾼的指针,跟踪引⽤特定对象的智能指针数。这称为引⽤计数(reference counting)。例如,赋值时,计数将加1, ⽽指针过期时,计数将减1。仅当最后⼀个指针过期时,才调⽤delete。这是shared_ptr采⽤的策略。 当然,同样的策略也适⽤于复制构造函数。每种⽅法都有其⽤途。 auto_ptr和unique_ptr: 上⾯也提到了,⽆论是auto_ptr还是unique_ptr,都是基于所有权的概念去解决可能出现的删除⼀个对象两次的问题的。这种情况下会有 什么问题呢?先看auto_ptr,看⼀个⼩例⼦: auto_ptr<string> films[2] = { auto_ptr<string> (new string("Fowl Balls")), auto_ptr<string> (new string("Duck Walks")) }; auto_ptr<string> pwin; pwin = films[0];//注:films[0]对内存失去了所有权 cout << films[0] << endl;//注:会出现错误,因为film[0]指向的内存此时已经
- 粉丝: 168
- 资源: 3万+
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助