• c++ 动态内存与智能指针


    c++ 动态内存与智能指针

    一、 动态内存

    1. 程序对象的生存期

      • 全局对象在程序启动时分配,在程序结束时销毁。

      • 对于局部自动对象,当我们进入其定义所在的程序块时被创建,在离开块时销毁。

      • 局部static对象在第一次使用前分配,在程序结束时销毁。

      • C++还支持动态分配对象。动态分配的对象的生存期与它们在哪里创建是无关的,只有当显式地被释放时,这些对象才会销毁。

    2. 动态内存管理

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

    二、智能指针

    为了更容易(同时也更安全)地使用动态内存,新的标准库提供了两种智能指针(smart pointer)类型来管理动态对象。智能指针的行为类似常规指针,**重要的区别是它负责自动释放所指向的对象**。
    

    (一)智能指针shared_ptr和unique_ptr共有操作:

    1. p->mem

      即(*p).mem

    2. p.get()

      返回保存的指针

    3. swap(p, q)p.swap(q)

      交换p、q中的指针

    (二)shared_ptr类

    shared_ptr<T>允许多个指针指向同一个对象;

    1. make_shared<T> p(q)

      p是q的拷贝,此操作递增q中的计数器。q中的指针必须能转换为T*。

    2. make_shared<T>()

      允许传入的参数与T的某个构造函数匹配。

    3. p.unique()

    4. p.use_count()

    5. 拷贝和赋值

      • 拷贝:无论何时我们拷贝一个shared_ptr,计数器都会递增。例如,当用一个shared_ptr初始化另一个shared_ptr,或将它作为参数传递给一个函数以及作为函数的返回值时,它所关联的计数器就会递增。

      • 赋值:当我们给shared_ptr赋予一个新值或是shared_ptr被销毁(例如一个局部的shared_ptr离开其作用域时,计数器就会递减。

      auto r = make_shared<int>(42);
      r = q; //给r赋值,另其指向另一个地址
      //递增q所指向对象的引用计数
      //递减r原来所指对象的引用技术
      //r原来指向的对象已没有引用者,会自动释放内存。
      
    6. 自动销毁所管理的对象:

      当指向一个对象的最后一个shared_ptr被销毁时,即引用计数为0时,shared_ptr类会自动销毁此对象。它是通过另一个特殊的成员函数——析构函数(destructor)完成销毁工作的。

    (三)unique_ptr类

    unique_ptr则“独占”所指向的对象。
    

    (四)weak_ptr类

    https://blog.csdn.net/Xiejingfa/article/details/50772571

    1. 标准库还定义了一个名为weak_ptr的伴随类,它是一种弱引用,指向shared_ptr所管理的对象,而不影响所指对象的生命周期,也就是将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。不论是否有weak_ptr指向,一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放。用于解决shard_ptr中可能存在的循环引用问题。

    2. 如何判断weak_ptr指向对象是否存在呢?

      C++中提供了lock函数来实现该功能。如果对象存在,lock()函数返回一个指向共享对象的shared_ptr,否则返回一个空shared_ptr。

      shared_ptr<A> pa = wp.lock()

      #include <iostream>
      #include <memory>
      using namespace std;
      class A{
      public:
          A() : a(3) { cout << "A Constructor..." << endl; }
          ~A() { cout << "A Destructor..." << endl; }
          int a;
      };
      
      int main() {
          shared_ptr<A> sp(new A());
          weak_ptr<A> wp(sp);
          if (shared_ptr<A> pa = wp.lock()){
              cout << pa->a << endl;
          }else{
              cout << "wp指向对象为空" << endl;
          }
      }
      
  • 相关阅读:
    falsk简单项目示例
    bootstrap基础
    flask models循环使用和migrate迁移脚本
    flask-script
    flask 钩子函数
    flask get和post请求使用
    flask SQLALchemy外键及约束
    flask SQLAlchemy
    关于虚拟机端口转发的一次理解和记录
    记录一次VMware与xshell远程链接的总结
  • 原文地址:https://www.cnblogs.com/qiangz/p/15953183.html
Copyright © 2020-2023  润新知