zoukankan      html  css  js  c++  java
  • 动态内存与智能指针

    动态内存与智能指针

    智能指针分为shared_ptr、unique_ptr、weak_ptr,他们负责自动释放所指向的对象,shared_ptr允许多个指针指向同一个对象,unique_ptr独占所指向的对象,weak_ptr是一种弱引用,指向shared_ptr所管理的对象,他们都定义在memory头文件中。

    shared_ptr类

    ​ 智能指针也是模板,创建智能指针:

    shared_ptr<string> p1;	//可以指向string
    shared_ptr<list<int>> p2;	//可以指向int的list
    shared_ptr<T> p;	//指向T
    

    ​ 默认初始化的智能指针中保存着一个空指针。智能指针的使用方法与普通指针相似,解引用智能指针返回它指向的对象。

    p.get();	//返回p中保存的指针
    swap(p,q); p.swap(q);	//交换p和q中的指针
    

    shared_ptr独有的操作:

    make_shared<T>(args);	//返回一个使用args初始化的T类型的对象的shared_ptr
    shared_ptr<T> p(q);		//p是q的拷贝,递增q中的引用计数,递减p中的引用计数,引用计数为0,就释放管理的内存
    p.unique();				//若p.use_count()为1,返回true,否则为false
    p.use_count();		//返回与p共享对象的智能指针数,可能很慢
    

    make_shared函数

    ​ 该函数在动态内存中分配一个对象并返回指向该对象的shared_ptr,定义在memory中:

    shared_ptr<int> p3=make_shared<int>(42);	//指向值为42的int的shared_ptr
    shared_ptr<string> p4=make_shared<string>(10,"9");	//指向值为“999999999”的string
    auto p5 = make_shared<int>();	//值初始化为0
    

    该函数使用参数构造给定类型的对象。

    智能指针的使用

    ​ 当指向一个对象的最后一个shared_ptr被销毁时,shared_ptr会自动通过自己的析构函数销毁此对象。看下面的StrBlob类,Strblob类通过shared_ptr实现类对象之间共享底层数据。

    StrBlob.h

    #include <vector>
    #include <memory> //share_ptr,unique_ptr
    #include <string>
    
    //Strblob类通过shared_ptr实现类对象共享底层数据
    //委托vector完成部分操作
    class StrBlob
    {
    public:
        using size_type = std::vector<std::string>::size_type;
        StrBlob();
        //使用可变形参列表
        //未使用explicit的initializer_list,可以在需要StrBlob对象时使用列表进行隐式类型转换,如作为函数的参数
        StrBlob(std::initializer_list<std::string> il);
        size_type size() const { return data->size(); }
        bool empty() const { return data->empty(); }
        //添加和删除元素
        void push_back(const std::string &s) const { data->push_back(s); }
        void pop_back();
        //元素访问
        std::string &front();
        const std::string &front() const;
        std::string &back();
        const std::string &back() const;
    
    private:
        std::shared_ptr<std::vector<std::string>> data;
        //若data[i]不合法,就抛出一个异常
        void check(size_type i, const std::string &msg) const;
    };
    

    StrBlob.cpp

    #include <iostream>
    #include "StrBlob.h"
    
    using namespace std;
    //make_shared用其参数构造给定类型的对象,返回动态内存的地址
    inline StrBlob::StrBlob() : data(make_shared<vector<string>>()) {}
    
    inline StrBlob::StrBlob(initializer_list<string> il) : data(make_shared<vector<string>>(il)) {}
    
    inline void StrBlob::check(size_type i, const string &msg) const
    {
        if (i >= data->size())
            throw out_of_range(msg);
    }
    
    inline string &StrBlob::front()
    {
        check(0, "front on empty StrBlob");
        return data->front();
    }
    //需要对const进行重载,const对象只能调用const成员函数
    //非const对象只能调用非const成员函数
    inline const string &StrBlob::front() const
    {
        check(0, "front on empty StrBlob");
        return data->front();
    }
    
    inline string &StrBlob::back()
    {
        check(0, "back on empty StrBlob");
        return data->back();
    }
    
    inline const string &StrBlob::back() const
    {
        check(0, "back on empty StrBlob");
        return data->back();
    }
    
    inline void StrBlob::pop_back()
    {
        check(0, "pop on empty StrBlob");
        data->pop_back();
    }
    
    int main()
    {
        StrBlob b1;
        {
            StrBlob b2 = {"a", "an", "the"};
            b1 = b2;
            b2.push_back("about");
        }
    
        return 0;
    }
    

    最终b1={"a", "an", "the","about"}。

  • 相关阅读:
    ceph集群jewel版本 rbd 块map 报错-故障排查
    基本的Ceph性能测试工具和方法
    dd命令的高级应用
    Ceph recover的速度控制
    Linux mount命令
    Centos7.2:搭建Ceph管理系统Inscope
    rpm --import /etc/pki/rpm-gpg/RPM* 有什么用?
    dd命令的解释
    Playbooks 中的错误处理
    Ansible之Playbooks的when语句
  • 原文地址:https://www.cnblogs.com/vlyf/p/11704699.html
Copyright © 2011-2022 走看看