我们使用智能指针来自动运行管理内存,避免对原始指针的使用不当而造成内存泄漏。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
C++里可能出现的内存问题大致有这么几个方面:
1. 缓冲区溢出。
2. 空悬指针 / 野指针。
3. 重复释放。
4. 内存泄漏。
5. 不配对的new[] / delete。
6. 内存碎片。
通过正确使用智能指针很容易解决前面5个问题:
1. 缓冲区溢出:用std::vector<char> / srd::string 或自己编写Buffer class 来管理缓冲区,自动记住用缓冲区的长度,并通过成员函数而不是裸指针来修改缓冲区。
2. 空悬指针 / 野指针:用shared_ptr / weak_ptr解决。
3. 重复释放:用scoped_ptr,只在对象析构的时候释放一次。 // unique_ptr
4. 内存泄漏:用scoped_ptr, 对象析构的时候自动释放内存。 // unique_ptr
5. 不配对的new[] / delete:把new[] 统统替换为 std::vector。
-------------引用自 陈硕 《Linux多线程服务端编程》
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面介绍了这几个智能指针的使用:
一、通过std::shared_ptr这种智能指针访问的对象采用共享所有权来管理其生存期。即内部采用引用计数方式,只有当应用计数为0时,会释放所指资源。
shared_ptr<string> p = make_shared<string>("apple");
我们尽可能使用std::make_shared而避免使用new 来创建对象。(可参考《Effective Modern C++》条款21.)
二、std::weak_ptr也是一个应用计数型智能指针,但它不增加对象的引用次数,即弱引用。可以说是std::shared_ptr的一种扩充。weak_ptr不控制对象的生命期,但它知道对象是否还活着(调用lock()) 。
shared_ptr<string> p = make_shared<string>("apple"); weak_ptr<string> wp(p); shared_ptr<string> sp = wp.lock(); // 如果对象还存在,返回一个shared_ptr,其中包含weak_ptr对象保留的信息。若死了,则返回一个空的shared_ptr。
if (sp) { } else { }
三、unique_ptr与shared_ptr不同的是unique_ptr对所管理的资源进行独享,unique_ptr不允许对资源进行拷贝。用来取代std::auto_ptr,可以替换boost库中的scoped_ptr。
unique_ptr<int> p1 = make_unique<int>(5); unique_ptr<int> p2(p1); // error unique_ptr<int> p3 = p1; // error
我们尽可能使用std::make_unique而避免使用new 来创建对象。(可参考《Effective Modern C++》条款21.)
测试代码(以shared_ptr为例智能指针日常使用, 测试环境: VS2017):
#include <iostream> #include <memory> #include <string> using namespace std; class apple { public: apple(const string& s = "0") : number(s) { } string getString() const { return number; } private: string number; }; class decorate final { public: decorate() = delete; // 不允许单独创建decorate对象 decorate(const shared_ptr<apple>& rhs) :pta(rhs){ } decorate(const decorate& rhs) : pta(make_shared<apple>(*rhs.pta)) { } decorate& operator=(const decorate& rhs); shared_ptr<apple> getPtr() const { return pta; } private: shared_ptr<apple> pta; }; decorate& decorate::operator= (const decorate& rhs) { if (this != &rhs) pta = rhs.pta; return *this; } int main() { shared_ptr<apple> pta = make_shared<apple>("yantai-apple"); decorate myDec(pta); cout << myDec.getPtr()->getString() << endl; return 0; }