zoukankan      html  css  js  c++  java
  • 浅谈C++的智能指针

    我们使用智能指针来自动运行管理内存,避免对原始指针的使用不当而造成内存泄漏。

    ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    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;
    }
  • 相关阅读:
    微软ASP.NET网站部署指南(4):配置项目属性
    iOS 设计模式之抽象工厂
    How can I move a MySQL database from one server to another?
    CentOS 7 上安装vim(默认未安装)
    How to resize slide dimensions without resizing any objects on the slide?
    CentOS 7.3 上安装docker
    美国留学访学(访问学者)必备信用卡
    西安理工大学税务登记证、银行账号信息
    Oracle联合多个子查询(inner join)
    linux tail
  • 原文地址:https://www.cnblogs.com/xiguas/p/9990312.html
Copyright © 2011-2022 走看看