• c++学习笔记—动态内存与智能指针浅析


    我们的程序使用内存包含以下几种:

    1. 静态内存用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量,在使用之前分配,在程序结束时销毁。
    2. 栈内存用来保存定义在函数内部的非static对象,仅在其定义的程序块运行时才存在。
    3. 堆内存用来存储动态分配的对象,即那些在程序运行时分配的对象,动态对象的生存周期由程序控制,当动态对象不再使用时,我们的代码必须显式的销毁他们。
     
    在c++中,普通对象离开它的作用域之后,它的的析构函数会自动调用,从而销毁这个对象,释放它所占用的内存,不会发生内存泄露。为了更容易的使用动态内存,新的标准库提供了两种智能指针类型来管理动态对象。分别为shared_ptr允许多个指针指向同一个对象,unique_ptr独占所指向的对象。
     
    一、shared_ptr类
    1、创建智能指针
    [cpp] view plaincopy
     
    1. shared_ptr<string> p1; //指向string  
    2. shared_ptr<list<int>> p2;//指向int的list  
    解引用一个智能指针返回它指向的对象
    2、基本用法
    成员函数有:
     
     
    make_shared函数:
    最安全的分配和使用动态内存的方法是调用make_shared标准库函数,此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr,定义方式为:
     
    [cpp] view plaincopy
     
    1. shared_ptr<vector <int>> vec = make_shared<vector <int>>();  //不传递任何参数,对象进行值初始化  
    2. shared_ptr<int> p1 = make_shared<int>(1);      //指向一个1的int的shared_ptr  
     
    实现智能指针原理:
    我们可以认为shared_ptr有一个关联的计数器,称为引用计数。无论何时我们拷贝一个shared_ptr,计数器都会递增,例如用一个shared_ptr初始化另一个shared_ptr,或将它作为参数传递给一个函数以及作为函数的返回值,它所关联的计数器都会递增,当我么给shared_ptr赋予一个新值或是shared_ptr被销毁时,计数器递减。一旦一个shared_ptr的计数器变为0时,它就会自动释放自己所管理的对象(通过析构函数)。shared_ptr还会自动释放相关联的内存。
     

    二、unique_ptr类
    某个时刻只能有一个unique_ptr指向一个给定对象,当unique_ptr被销毁时,它所指向的对象也被销毁。
    1、创建unique_ptr指针
    初始化必须采用直接初始化形式,并且不支持普通的拷贝和赋值操作
    [cpp] view plaincopy
     
    1. unique_ptr<double> p1;   //指向double,初始化为一个空指针  
    2. unique_ptr<int> p2(new int(1));   //p2指向一个值为1的int  
    2、基本用法
    成员函数:

     
    普通指针与智能指针用法示例
     
    [cpp] view plaincopy
     
    1. #include "stdafx.h"  
    2. #include <vector>  
    3. #include <iostream>  
    4. #include <memory>  
    5. using namespace std;  
    6.   
    7. vector<int> alloc_new()      //使用内置指针  
    8. {  
    9.     vector<int> *vec = new vector<int>;  
    10.     return *vec;  
    11.     delete vec;  
    12. }  
    13.   
    14. vector<int> alloc_shared()  
    15. {  
    16.     shared_ptr<vector <int>> vec=make_shared<vector <int>>();    //使用智能指针  
    17.     return *vec;  
    18. }  
    19. vector<int> input(vector<int> &ve)  
    20. {  
    21.     ve = alloc_new();  
    22.     int i;  
    23.     while (cin >> i)  
    24.     {  
    25.         ve.push_back(i);  
    26.     }  
    27.     return ve;  
    28. }  
    29. void print(vector<int> pvec)  
    30. {  
    31.     pvec = input(pvec);  
    32.     for (auto it = pvec.begin(); it != pvec.end(); it++)  
    33.         cout << *it << endl;  
    34. }  
    35. int _tmain(int argc, _TCHAR* argv[])  
    36. {  
    37.     vector<int> i;  
    38.     print(i);  
    39.     return 0;  
    40. }  
  • 相关阅读:
    IIS 禁止自动回收
    误删除系统帐户且SA被禁用,如何修复?单用户模式登录可解决。
    不到100行代码实现SHELL环境下图形化的IP设置功能
    2021总结
    快排
    Windows 10 修改用户名及Users文件夹
    DATUM支持不同格式(JSON,CSV,SQL,XML等)的在线模拟数据生成器
    记:云服务器被暴破感染bioset
    前端项目修改npm/yarn配置文件来加速包下载
    十个前端常见手写功能
  • 原文地址:https://www.cnblogs.com/xujian2014/p/4223163.html
Copyright © 2020-2023  润新知