• c++基础(六)——动态内存


      在我们的程序中,静态内存——用来保存局部 static 对象,类 static数据成员,以及定义在任何函数之外的变量。栈内存——用来保存定义在函数内的非 static 对象。分配在  静态内存 或 栈内存中的对象由编译器自动创建和销毁。对于栈内存,仅在其定义的程序块运行时才存在,static对象在使用之前分配,在程序结束时销毁。

      除此之外,每个程序还拥有一个内存池,这部分内存被称为自由空间(堆),程序用堆来存储动态分配的对象,——即那些在程序运行时分配的对象。

    1. 动态内存和智能指针

      在C++中,动态内存的管理是通过一对运算符来完成的:new,在动态内存中为对象分配空间并返回一个指向该对象的指针,我们可以选择对对象进行初始化;delete,接受一个动态指针,销毁该对象,并释放与之关联的内存。

      新的标准提供了两种智能指针(smart pointer)类型来管理动态对象。shared_ptr允许多个指针指向同一个对象;unique_ptr则“独占”所指向的对象。标准库还定义了一个名为weak_ptr的伴随类,指向shared_ptr所管理的对象。这三种类型都定义在memory中。

    1.1 share_ptr 类

      类似vector智能指针也是模板。

    1 shared_ptr<string> p1;    //shared_ptr,可以指向string
    2 shared_ptr<list<int>> p2;    //shared_ptr,可以指向int的list

      智能指针的使用方法和普通指针类似,解引用返回它指向的对象,如果在一个条件判断中使用智能指针,效果就是检测它是否为空,

    1 // 如果 p1 不为空,检查它是否指向一个空 string
    2 if (p1 && p1->empty()) // p->mem -- (*p).mem
    3     *p1 = "ds"

    1.2 make_shared 函数

      最安全的分配和使用动态内存的方法是调用一个名为make_shared的标准库函数。此函数在动态内存中分配一个对象并初始化它,返回指向此对象的shared_ptr。与智能指针一样,make_shared也定义在memory中。

    1 //指向一个值为42的int的shared_ptr
    2 shared_ptr<int> p3 = make_shared<int>(42);
    3 //p4指向一个值为”999999999”的string
    4 shared_ptr<string> p4 = make_shared<string>(10,'9');
    5 //p5指向一个值初始化的int,即,值为0
    6 shared_ptr<int> p5 = make_shared<int>();
    7 auto p6 = make_share<vector<string>>();

      

    1.3 share_ptr 的拷贝和赋值

      当进行拷贝或赋值操作时,每个shared_ptr都会记录有多少个其他shared_ptr指向相同的对象:

    1 auto p = make_shared<int>(42);    //p指向的对象只有p一个引用者
    2 auto q(p);    //p和q指向相同对象,此对象有两个引用者

      我们可以认为每个shared_ptr都有一个关联的计数器,通常称其为引用计数(reference count)。无论何时我们拷贝一个shared_ptr,计数器都会递增;当我们给shared_ptr赋予一个新值或是shared_ptr被销毁时,计算器就会递减。
    一旦一个shared_ptr的计数器变为0,它就会自动释放自己所管理的对象

    1 auto r = make_shared<int>(42);    //r指向的int只有一个引用者
    2 r = q;    //给r赋值,令它指向另一个地址
    3           //递增q指向的对象的引用计数
    4           //递减r原来指向对象的引用计数
    5           //r原来指向的对象已没有引用者,会自动释放

    1.4 share_ptr 自动销毁所管理的对象

      当指向一个对象最后一个 share_ptr 被销毁时,share_ptr 类会自动销毁此对象。它是通过另一个特殊的成员函数——析构函数完成销毁工作的

    2. shared_ptr 和 new 结合使用

      我们可以使用 new 返回的指针来初始化智能指针,智能指针是一个类,分装了一个原始的 C++ 指针,用以管理所指对象的生命期。

    1 shared_ptr<double> p1;    //shared_ptr可以指向一个double
    2 shared_ptr<int> p2(new int (42));    //p2指向一个值为42的int

      接受指针参数的智能指针构造函数是explicit的。因此,我们不能将一个内置指针隐式转换为一个智能指针,必须使用直接初始化形式来初始化一个智能指针:

    1 shared_ptr<int> p1 = new int(1024);    //错误:必须使用直接初始化形式
    2 shared_ptr<int> p2(new int (1024));    //正确:使用了直接初始化

      出于相同的原因,一个返回shared_ptr的函数不能在其返回语句中隐式转换一个普通指针:

    1 shared_ptr<int> clone(int p){
    2     return new int(p);    //错误:隐式转换为shared_ptr<int>
    3 }
    4 
    5 shared_ptr<int> clone(int p){
    6    
    7     return shared_ptr<int>(new int(p)); //正确:显式地用int*创建shared_ptr<int>
    8 }

      默认情况下,一个用来初始化智能指针的普通指针必须指向动态内存,因为智能指针默认使用delete释放它所关联的对象。我们可以将智能指针绑定到一个指向其他类型的资源的指针上,但是为了这样做,我们必须自己提供操作来代替  delete 。

        

      

  • 相关阅读:
    Shiro笔记(三)shiroFilter拦截器配置原则
    Shiro笔记(二)Shiro集成SpringMVC的环境配置
    Shiro笔记(一)Shiro整体介绍
    javaNIO的总结
    Redis的工作流程
    Nginx的配置安装和使用
    Linux下java开发环境配置总结
    php 基础知识 post 和get 两种传输方式的区别
    php 高级 多台web服务器共享session的方法
    php 基础知识 SESSION 和 COOKIE 的区别
  • 原文地址:https://www.cnblogs.com/KongHuZi/p/11372062.html
Copyright © 2020-2023  润新知