C++ 智能指针、share_ptr,unique_ptr,weak_ptr、STL标准模板库(vector,list)、关联式容器map 6.6

智能指针 smart pointer

在你创建一个指针空间时,程序中发生任何异常时我们都需要去释放这个自定义空间,但我们一般的释放内存的程序在最后面,万一程序中途中断就释放不了
    (^U^)ノ~YO
作用:
    用来防止内存泄漏,用来在创建这个智能指针后,通过智能指针去使用这块内存,而不需要关心的释放,释放时由系统自动释放
    每多个指针指向内存,则引用计数器+1

shared_ptr

共享资源所有权的指针,多个共享的智能指针指向同一块内存
    
/*===============================================
*   文件名称:share_ptr.cpp
*   创 建 者: memories
*   创建日期:2023年06月06日
*   描    述:have a nice day
================================================*/
#include <iostream>
#include <memory>
using namespace std;


class Demo
{
    public:
        Demo(int size):len(size),p(nullptr)
    {
        if(len > 0)
        {
            cout << "Demo::Demo(),len=" << len << endl;
            p = new int[len];
        }

    }
       virtual ~Demo()
        {
            if(p != nullptr)
            {
                delete []p;
                p = nullptr;
                cout << "delete success" << endl;
            }
        }
       void show()
       {
           cout << "Demo::show()" << endl;
       }
    private:
        int len;
        int *p;
};

void debug()
{
    cout << "---------------" << endl;
}

void func()
{
    ///模板类
    shared_ptr<Demo> p = make_shared <Demo>(100);//定义了一个名为p的共享指针,其大小为Demo的大小,要使用Demo类的数据类型。。。。p指向由make_shared创建的Demo类的空间
    debug();
   // shared_ptr<Demo> p ( new Demo(100));
   // p->show();
   // 获得demo的对象
    (*p).show();
    debug();
    //获得demo对象的指针
    Demo *pDemo = p.get();//这个.操作的是shared_ptr类里的,相当于p是shared_ptr中的对象,获得指向Demo类的指针;
    pDemo->show();
    debug();
    用p2也指向Demo/
    shared_ptr<Demo> p2 = p;
    p2->show();
    debug();
    //查找指向Demo类的指针个数/
    cout << "reference cout = " << p.use_count() << endl;
    cout << "reference cout = " << p2.use_count() << endl;
    ///让p2放弃指向Demo/
    p2.reset();
    if(p2 == nullptr)
    {
        cout << "p2 is a null ptr" << endl;
    }
    else
        cout << "p2 is still alive" << endl;
    cout << "reference cout = " << p.use_count() << endl;
    cout << "reference cout = " << p2.use_count() << endl;
}

int main()
{
     func();
    

      return 0;
}

//
shared_ptr<Demo> p = make_shared <Demo>(100);
这行代码使用了 C++11 中的智能指针 `shared_ptr`,并创建了一个名为 `p` 的指向 `Demo` 类型对象的智能指针。

`make_shared` 是一个模板函数,用于在动态内存中创建一个对象并返回一个指向该对象的 `shared_ptr` 智能指针。在这里,`make_shared` 接受一个 `Demo` 类型的参数 `100`,用于初始化 `Demo` 类型对象的成员变量。

因此,这行代码的作用是创建一个 `Demo` 类型对象,并将其封装在一个 `shared_ptr` 智能指针中,然后将该智能指针赋值给 `p` 变量。这样做的好处是,`shared_ptr` 会自动管理对象的生命周期,当没有任何智能指针指向该对象时,`shared_ptr` 会自动释放该对象的内存空间,避免了内存泄漏的问题。

unique_ptr

独占资源所有权的指针,一块内存只能被一个指针独占所有权,但是所有权可以转移
    
/*===============================================
*   文件名称:unique_ptr.cpp
*   创 建 者: memories
*   创建日期:2023年06月06日
*   描    述:have a nice day
================================================*/
#include <iostream>
#include <memory>
using namespace std;


class Demo
{
    public:
        Demo(int size):len(size),p(nullptr)
    {
        if(len > 0)
        {
            cout << "Demo::Demo(),len=" << len << endl;
            p = new int[len];
        }

    }
       virtual ~Demo()
        {
            if(p != nullptr)
            {
                delete []p;
                p = nullptr;
                cout << "delete success" << endl;
            }
        }
       void show()
       {
           cout << "Demo::show()" << endl;
       }
    private:
        int len;
        int *p;
};

void debug()
{
    cout << "---------------" << endl;
}

void func()
{
    ///模板类
    unique_ptr<Demo> p = make_unique <Demo>(100);//定义了一个名为p的独占指针,其大小为Demo的大小,要使用Demo类的数据类型。。。。p指向由make_unique创建的Demo类的空间
    debug();
    p->show();
    debug();
   // 获得demo的对象
    (*p).show();
    debug();
    //获得demo对象的指针
    Demo *pDemo = p.get();//这个.操作的是shared_ptr类里的,相当于p是shared_ptr中的对象,获得指向Demo类的指针;
    pDemo->show();
    debug();
    //不允许独占的智能指针指向同一块内存
   // unique_ptr<Demo> p2 = p; 是错误的
    unique_ptr<Demo> p2 = move(p);//将独占的智能指针转移
    p2->show();
    (*p2).show();
    if(p != nullptr )
    {
        cout << "p is still alive" << endl;
    }
    else
        cout << "p is a null ptr" << endl;
    debug();
    pDemo = p2.get();//把pDemo的所有权从p转移到p2
    pDemo->show();
    debug();
}

int main()
{
     func();
   

      return 0;
}

weak_ptr

共享资源的观察者,需要和std::shared_ptr 一起使用ヽ( ̄ω ̄( ̄ω ̄〃)ゝ
不影响资源的生命周期,共享指针赋值的时候引用的计数器会+1,它是强引用,使用weak_ptr不引发引用计数器的增加,是一个共有资源的观察者,
                                  
                                  
                                  
/*===============================================
*   文件名称:weak_ptr.cpp
*   创 建 者: memories
*   创建日期:2023年06月06日
*   描    述:have a nice day
================================================*/
#include <iostream>
#include <memory>
using namespace std;

class B;

class A
{
    public:
        A()
        {
            cout << "A::A()" << endl;
        }
      virtual  ~A()
        {
            cout << "A::~A()" << endl;
        }
      void show()
      {
          cout << "A::show()" << endl;
      }
      //shared_ptr<B> pointer;
      weak_ptr<B> pointer;
};


class B
{
    public:
        B()
        {
            cout << "B::B()" << endl;
        }
      virtual  ~B()
        {
            cout << "B::~B()" << endl;
        }
      void show()
      {
          cout << "B::show()" << endl;
      }
      //shared_ptr<A> pointer;
      weak_ptr<A> pointer; 
};

void debug()
{
    cout << "---------------" << endl; 
}

void func()
{
    shared_ptr<A> sp_a = make_shared<A>();
    shared_ptr<B> sp_b = make_shared<B>();
    debug();
    
    cout << "reference count of sp_a is " << sp_a.use_count() << endl;
    cout << "reference count of sp_b is " << sp_b.use_count() << endl;
    sp_a->show();
    sp_b->show();
    debug();
    sp_a->pointer = sp_b;//和std::shared_ptr 一起使用
    sp_b->pointer = sp_a;
    cout << "reference count of sp_a is " << sp_a.use_count() << endl;
    cout << "reference count of sp_b is " << sp_b.use_count() << endl;
    sp_a->show();
    sp_b->show();
    debug();

}
int main()
{
     func();

      return 0;
}
                          

STL标准模板库

  1 容器(Container),是一种数据结构,如list,vector,和deque ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器
	  2 迭代器(Iterator),提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。
	  3 算法(Algorithm),是用来操作容器中的数据的模板函数。
	    例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,
		因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用;
	  4 仿函数(Functor)仿函数(functor),就是使一个类的使用看上去象一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了
	  5 适配器(Adaptor)适配器是使一种事物的行为类似于另外一种事物行为的一种机制”,适配器对容器进行包装,使其表现出另外一种行为。
	    例如,stack<int, vector<int> >实现了栈的功能,但其内部使用顺序容器vector<int>来存储数据。(相当于是vector<int>表现出了栈的行为)
	  6 分配器(allocator)用于分配管理内存空间。其实我们可以把allocator看成一个简易的内存池,其主要适用于在使用容器时,对内存空间的动态分配

vector 向量

 将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时  
     
     
     /*===============================================
 *   文件名称:vector.cpp
 *   创 建 者: memories
 *   创建日期:2023年06月06日
 *   描    述:have a nice day
 ================================================*/
#include <iostream>
#include <vector>
using namespace std;

void debug()
{
    cout << "-------------------------------------------------------" << endl;
}

void printVec(int id, vector<int>& vecInt)
{
    cout << id << "==[";
    for(int item:vecInt)
        cout << item << ",";
    cout << "]" << endl;
}

int main()
{
    vector<int> vecInt;//vector是个模板类
    cout << "capacity=" << vecInt.capacity() << endl;//capacity()容量由vector自行开辟
    cout << "size=" << vecInt.size() << endl;//

    for(int i=1;i<=10;i++)
    {
        vecInt.push_back(i);//push_back()压栈,数据第一个在最下部
    }
    cout << "capacity=" << vecInt.capacity() << endl;
    cout << "size=" << vecInt.size() << endl;
    for(int i=11;i<=200;i++)
    {
        vecInt.push_back(i);
    }
    cout << "capacity=" << vecInt.capacity() << endl;
    cout << "size=" << vecInt.size() << endl;

    cout << vecInt[100] << endl;
    /遍历的方法1//
    //通过下标操作符
    for(int i=0;i<vecInt.size();i++)
    {
        cout << vecInt[i] << ",";
    }
    cout << endl;
    /遍历的方法2//
    //通过at()函数
    for(int i=0;i<vecInt.size();i++)
    {
        cout << vecInt.at(i) << ",";
    }
    cout << endl;
    /遍历的方法3//
    //通过 int item:使用新的for方法
    for( int item:vecInt )
    {
        cout << item << ",";
    }
    cout << endl;

    4使用迭代器iterator
    //
    vector<int>::iterator iter;//定义一个迭代器,可以看作特殊的指针
    vector<int>::reverse_iterator riter;
    for(iter = vecInt.begin(); iter != vecInt.end();iter++)
    {
        cout << *iter << ",";
    }
    cout << endl;

     debug();
    ///删除部分数据1
    for(int i=0;i<100;i++)
    {
        vecInt.pop_back();
    }
    printVec(1,vecInt);
    /反向迭代器遍历数据2///
    for(auto iter = vecInt.rbegin();iter != vecInt.rend();iter++)
    {
        cout << *iter << ",";
    }
    cout << endl;
    ///删除所有数据2
    vecInt.clear();
    if (vecInt.empty() == true)
        cout << "now there is no data" << endl;
    debug();
    /不同的构造函数//
    vector<int> v2(100,1000);//构造时往容器里放置100个1000
    printVec(2,v2);
    debug();
    vector<int> v3(v2);//拷贝构造
    printVec(3,v3);
    debug();
    return 0;
}

deque

 是“double-ended queue”的缩写,可以随机存取元素(用索引直接存取),数组头部和尾部添加或移除元素都非常快速。但是在中部安插元素比较费时	  

list 双向链表

双向链表,不提供随机存取(按顺序走到需存取的元素),在任何位置上执行插入或删除动作都非常迅速,内部只需调整一下指针
    
    /*===============================================
*   文件名称:list.cpp
*   创 建 者: memories
*   创建日期:2023年06月06日
*   描    述:have a nice day
================================================*/
#include <iostream>
#include <list>
using namespace std;

void printList(int id,list<int>& list)
{
    cout << id << "=[" ;
    for(int item:list)
    {
        cout << item << ",";
    }
    cout << "]" << endl;
}

void debug()
{
    cout << "--------------------------------------------------------" << endl;
}

int main()
{
    list<int> liInt(10,100);
    printList(1,liInt);

    list<int> li;
    for(int i=0;i<100;i++)
    {
        if(i%2 == 0)
        {
            li.push_front(i);
        }
        else
            li.push_back(i);
    }
    printList(2,li);
    debug();
    //使用迭代器遍历//
    for(auto iter = li.begin();iter != li.end();iter++)
    {
        cout << *iter << ",";
    }
    cout << endl;
    debug();
    //使用反向迭代器遍历//
    for(auto iter = li.rbegin();iter != li.rend();iter++)
    {
        cout << *iter << ",";
    }
    cout << endl;
    debug();
    ///删除数据元素
    for(int i=0;i<40;i++)
    {
        if(i%2 == 0)
            li.pop_front();
        else
            li.pop_back();
    }
    printList(3,li);
    debug();
    ///删除全部数据
    li.clear();
    cout << "size of li = " << li.size() << endl;
    if(li.empty() == true)
    {
        cout << "now li is empty" << endl;
    }
      return 0;
}

关联式容器(Associated containers) map

      Set/Multiset
	    内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次,Multisets内可包含多个数值相同的元素,内部由二叉树实现,便于查找
	  
	  Map/Multimap
	    Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次,Multimaps内可包含多个数值相同的元素,内部由二叉树实现,便于查找
    
/*===============================================
*   文件名称:map.cpp
*   创 建 者: memories
*   创建日期:2023年06月06日
*   描    述:have a nice day
================================================*/
#include <iostream>
#include <map>
#include <string>
using namespace std;

void debug()
{
    cout << "-----------------------------------------------" << endl;
}

void printMap(int id,map<int,string>& map)
{
    cout << id << ":" << endl;
    for(auto item: map)
    {
        cout << item.first << "->" << item.second << endl;
    }
    cout << endl;
}

int main()
{

    map<int,string> smap = {{1,"zhangsan"}, {2,"lisi"},{3,"wangwu"}};//三对键值
    printMap(1,smap);
    新增数据
    smap[4] = "jackson";
    printMap(2,smap);
    覆盖数据
    smap[4] = "jocker";
    printMap(3,smap);

    /迭代器//
  //  map<int,string>::iterator iter;
    for(auto iter = smap.begin();iter != smap.end();iter++)
    {
        cout << iter->first << "->" << iter->second << endl;
    }
    cout << endl;
    for(auto iter = smap.rbegin();iter != smap.rend();iter++)
    {
        cout << iter->first << "->" << iter->second << endl;
    }
    cout << endl;
/通过某一键值找到其值/
    auto iter = smap.find(3);
    cout << iter->first << "->" << iter->second << endl;
    auto itere = smap.find(4);
    if(itere != smap.end())
    {
    cout << itere->first << "->" << itere->second << endl;
    }
    else
    {
        cout << "didn't find value for 4" << endl;
    }
/删除数据//
    smap.erase(itere);
    printMap(5,smap);
/全部删除//   
    smap.clear();
    printMap(6,smap);
    
      return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

孤独memories

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值