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

     参考https://www.cnblogs.com/lanxuezaipiao/p/4132096.html#top 与c++ primer第五版(p432)

    1.动态内存与智能指针

    • 智能指针包含在头文件<memory>中,shared_ptr、unique_ptr、weak_ptr。
    • 智能指针与普通指针区别在于,它负责自动释放所指向的对象。
    • shared_ptr 允许多个指针指向同一个对象,unique_ptr 则独占所指向的对象,二者管理底层指针的方式不同。
    • 智能指针类似于vector,也是模板

       程序使用动态内存的三个原因:

    1. 程序不知道自己需要使用多少个元素;例如容器类
    2. 程序不知道所需对象的准确类型; 15章涉及
    3. 程序需要在多个对象之间共享数据。

    2.share_ptr

    2.1 make_shared函数

      此函数在动态内存中分配一个对象并初始化,返回指向该对象的shared_ptr

    //指向了一个值为42的int的shared_ptr
    shared_ptr<int> p3 = make_shared<int>42;
    //传递的参数必须与string的某个构造函数相匹配
    shared_ptr<string>p4=make_shared<string>(10,'9');
    View Code

    2.2 shared_ptr的拷贝与赋值

      每一个shared_ptr都关联一个计数器,称为引用计数。

          一旦计数器为0,会自动释放所管理的对象,即shared_ptr的析构函数销毁对象,释放其内存。

    auto r = make_shared<int>(42);
    r = p; //给r赋值,递减r原来指向对象的引用计数

    2.3 使用动态生存期的类

    前面我们使用的类中,分配的资源与使用的对象的生存周期一致;如下:

    vector<int> v1;
    {
        vector<int> v2={1,2};
        v1=v2;
    } //v2和它的元素均被销毁;
      // v1中有三个元素,是v2 的拷贝

    但某些类分配的资源与使用的对象的生存周期相互独立

    Blob<string> b1;
    {//新作用域
        Blob<string> b2={"1","1"};
        b1=b2;
    }//b2被销毁,但b2中的元素没有销毁

        StrBlob是一个管理string的类,借助标准库容器vector,以及动态内存管理类shared_ptr,我们将vector保存在动态内存里,这样就能在多个对象之间共享内存。strBlob的data成员是一个指向vector<string>的shared_ptr,因此StrBlob的赋值不会拷贝vector的内容,而是多个StrBlob对象共享一个vector对象。

    StrBlob.h

     1 #include <vector>
     2 #include <string>
     3 #include <memory>
     4 using namespace std;
     5 class StrBlob
     6 {
     7 public:
     8     typedef  vector<string>::size_type  size_type;
     9     //构造函数 
    10     StrBlob();
    11     StrBlob(initializer_list<string> il);
    12        //大小 
    13     size_type size() const {return data->size();}
    14     bool empty() const {return data->empty();};
    15     //添加和删除元素
    16     void push_back(const string& t) { data->push_back(t);};
    17     void pop_back();
    18     //元素访问
    19     std::string& front();
    20     std::string& back();
    21 private:
    22     std::shared_ptr<vector<string>> data;
    23     //data[i]不合法时,抛出异常
    24     void check(size_type i, const string &msg) const;
    25 };
    View Code

    定义成员函数及使用:

     1 #include<iostream>
     2 #include "StrBlob.h"
     3 #include <exception>
     4 using namespace std;
     5 //默认构造函数 
     6 StrBlob::StrBlob():data( make_shared<vector<string>>() ){}
     7 //接受单一参数的构造函数 
     8 StrBlob::StrBlob(initializer_list<string> il):
     9     data( make_shared<vector<string>>(il) ){}
    10 //检查一个给定索引是否在范围内 
    11 void StrBlob::check(size_type i, const std::string &msg) const
    12 {
    13     if(i >= data->size())
    14         throw std::out_of_range(msg);
    15 }
    16 string& StrBlob::front()
    17 {
    18     //vector为空,会抛出异常 
    19     check(0, "front on empty StrBlob");
    20     return data->front();
    21 }
    22 string& StrBlob::back()
    23 {
    24     check(0, "back on empty StrBlob");
    25     return data->back();
    26 }
    27 
    28 void StrBlob::pop_back()
    29 {
    30     check(0, "pop_back on empty StrBlob");
    31     return data->pop_back();
    32 }
    33 
    34 int main(){
    35     StrBlob b1;
    36     StrBlob b2={"wang","dewd","dwerr"};
    37     b1=b2;
    38     b2.push_back("about");
    39     cout<<b1.size()<<" "<<b1.front();
    40     return 0;
    41 } 
    View Code

     

  • 相关阅读:
    nginx的优化
    apache日志轮询技术
    PV IP UV的概念介绍
    日志文件记录的重要性
    linux chmod 755
    ssh免密码登录机器(使用公钥和秘钥进行加密来实现)
    ffmpeg基础
    linux使用grep和find查找内容
    为什么我们会越来越穷?
    从我干程序员开始 我就不准备干这个行业
  • 原文地址:https://www.cnblogs.com/wsl96/p/13088201.html
Copyright © 2011-2022 走看看