动态内存 与 智能指针

 参考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

 

原文地址:https://www.cnblogs.com/wsl96/p/13088201.html