C++ 智能指针_详细解释

C++智能指针的使用与实现 1.什么是智能指针  C++的智能指针其实就是对普通指针的封装(即封装成一个类),通过重载 * 和 ->两个运算符,使得智能指针表现的就像普通指针一样。 2.智能指针的作用            C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理。程序员自己管理堆内存可以提高 了程序的效率,但是整体来说堆内存的管理是麻烦的,C++11中引入了智能指针的概念,... 阅读详情

前置说明

智能指针基于RAII(资源获取即初始化)机制,自动管理堆内存,核心解决裸指针的内存泄漏问题:把堆内存的生命周期绑定到栈上的智能指针对象,当智能指针对象超出作用域时,析构函数会自动释放绑定的堆内存,无需手动delete。

C++ 中的裸指针(int* p = new int;)需要手动管理内存:

  • 忘记delete会导致内存泄漏;
  • 多次delete会导致未定义行为;
  • 异常场景下(比如delete前抛出异常),内存也无法释放。

C++ 标准库在<memory>头文件中提供了三种核心智能指针:unique_ptr、shared_ptr、weak_ptr,其中auto_ptr已被废弃(设计缺陷)。

  1. unique_ptr是独占式智能指针(轻量、高效),shared_ptr是共享式(引用计数),weak_ptr辅助shared_ptr解决循环引用;
  2. 使用智能指针的核心原则:优先选unique_ptr,避免裸指针与智能指针混用,警惕shared_ptr的循环引用。

智能指针的使用原则:

  1. 优先使用unique_ptr(高效、无额外开销),仅在需要共享所有权时使用shared_ptr;
  2. 避免用同一个裸指针创建多个智能指针(会导致重复释放);
  3. 不要手动delete智能指针管理的裸指针(智能指针析构时会再次delete);
  4. shared_ptr的循环引用必须用weak_ptr解决;
  5. 优先使用make_unique/make_shared创建智能指针(异常安全、更高效)。

1. std::unique_ptr(独占式智能指针)

特性与使用场景

  • 独占所有权:同一时间只有一个 unique_ptr 指向资源,拷贝构造 / 赋值被禁用,仅支持移动(std::move);
  • 轻量级:无额外内存开销(仅封装裸指针 + 删除器),效率接近裸指针;
  • 适用场景:函数返回值、容器元素(如 std::vector<unique_ptr<Foo>>)、独占资源的管理(如文件句柄、网络连接)。

核心签名(类模板声明)

// 基础版本(针对单个对象)
template <class T, class Deleter = std::default_delete<T>>
class unique_ptr;

// 数组特化版本(针对动态数组 new T[])
template <class T, class Deleter>
class unique_ptr<T[], Deleter>;
部分含义
template <class T, class Deleter = std::default_delete<T>>模板参数:- T:智能指针指向的对象类型(如 int、std::string、自定义类);- Deleter:删除器类型(负责释放资源的函数 / 仿函数),默认是 std::default_delete<T>(调用 delete 释放单个对象);
unique_ptr<T[], Deleter>数组特化版本:专门处理 new T[] 分配的动态数组,默认删除器会调用 delete[],而非普通版本的 delete;

关键成员函数签名(常用)

// 1. 移动构造(独占所有权,仅支持移动,禁止拷贝)
template <class U, class E>
unique_ptr(unique_ptr<U, E>&& u) noexcept;

// 2. 重置(释放当前资源,接管新资源)
void reset(pointer p = pointer()) noexcept;

// 3. 释放所有权(返回裸指针,智能指针不再管理)
pointer release() noexcept;

// 4. C++14 辅助创建函数(更安全,避免裸指针)
template <class T, class... Args>
unique_ptr<T> make_unique(Args&&... args);

// 数组版本的make_unique
template <class T>
unique_ptr<T> make_unique(size_t n);

    示例代码

    #include <iostream>
    #include <memory>
    
    class MyClass {
    public:
        MyClass(int val) : value(val) {
            std::cout << "MyClass 构造:" << value << std::endl;
        }
        ~MyClass() {
            std::cout << "MyClass 析构:" << value << std::endl;
        }
        void show() {
            std::cout << "值:" << value << std::endl;
        }
    private:
        int value;
    };
    
    int main() {
        // 1. 创建shared_ptr(推荐用make_shared,更高效)
        std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>(10);
        std::cout << "引用计数:" << ptr1.use_count() << std::endl; // 输出:1
    
        // 2. 拷贝,引用计数+1
        std::shared_ptr<MyClass> ptr2 = ptr1;
        std::cout << "引用计数:" << ptr1.use_count() << std::endl; // 输出:2
        std::cout << "引用计数:" << ptr2.use_count() << std::endl; // 输出:2
    
        // 3. 多个指针共享资源
        ptr1->show(); // 输出:值:10
        ptr2->show(); // 输出:值:10
    
        // 4. 重置指针,引用计数-1
        ptr1.reset();
        std::cout << "引用计数:" << ptr2.use_count() << std::endl; // 输出:1
    
        // 5. 管理数组(C++17+支持make_shared数组,C++11/14需手动new)
        std::shared_ptr<int[]> arr_ptr(new int[5]{1,2,3,4,5});
        arr_ptr[1] = 200;
        std::cout << arr_ptr[1] << std::endl; // 输出:200
    
        return 0; // ptr2析构,引用计数变为0,资源释放
    }
    

    2. std::shared_ptr(共享式智能指针)

    特性与使用场景

    • 共享所有权:多个 shared_ptr 指向同一资源,每新增一个shared_ptr指向该资源,引用计数 + 1;每销毁一个shared_ptr,引用计数 - 1;引用计数为 0 时自动释放资源;
    • 线程安全:引用计数的增减是原子操作(但访问 / 修改指向的对象需手动加锁);
    • 适用场景:需要多个对象共享同一资源的场景(如多线程访问同一数据、对象树的交叉引用)。

    核心签名(类模板声明)

    template <class T>
    class shared_ptr;
    

    关键辅助函数 / 转换函数签名

    // 1. 高效创建(一次内存分配:对象+控制块,比直接new更优)
    template <class T, class... Args>
    shared_ptr<T> make_shared(Args&&... args);
    
    // 2. 类型转换(对应普通指针的cast,保证引用计数正确)
    // static_cast 等价版本
    template <class T, class U>
    shared_ptr<T> static_pointer_cast(const shared_ptr<U>& r) noexcept;
    
    // dynamic_cast 等价版本(运行时类型检查)
    template <class T, class U>
    shared_ptr<T> dynamic_pointer_cast(const shared_ptr<U>& r) noexcept;
    
    // const_cast 等价版本
    template <class T, class U>
    shared_ptr<T> const_pointer_cast(const shared_ptr<U>& r) noexcept;
    

    核心成员函数签名

    // 1. 拷贝构造(增加引用计数)
    template <class U>
    shared_ptr(const shared_ptr<U>& r) noexcept;
    
    // 2. 赋值重载(引用计数增减)
    template <class U>
    shared_ptr& operator=(const shared_ptr<U>& r) noexcept;
    
    // 3. 获取引用计数
    long use_count() const noexcept;
    
    // 4. 检查是否是唯一持有者
    bool unique() const noexcept;
    
    // 5. 重置(释放当前引用,引用计数-1)
    void reset() noexcept;
    
    部分含义
    template <class T>仅需指定指向的对象类型 T,控制块(存储引用计数、删除器等)是内部隐式创建的;
    make_shared<Args&&... args>完美转发参数给 T 的构造函数,在堆上创建 T 对象并绑定到 shared_ptr;
    static/dynamic/const_pointer_cast避免直接对 shared_ptr 的裸指针做 cast(会导致多个控制块),保证类型转换后引用计数统一;

      示例代码

      #include <iostream>
      #include <memory>
      
      class MyClass {
      public:
          MyClass(int val) : value(val) {
              std::cout << "MyClass 构造:" << value << std::endl;
          }
          ~MyClass() {
              std::cout << "MyClass 析构:" << value << std::endl;
          }
          void show() {
              std::cout << "值:" << value << std::endl;
          }
      private:
          int value;
      };
      
      int main() {
          // 1. 创建shared_ptr(推荐用make_shared,更高效)
          std::shared_ptr<MyClass> ptr1 = std::make_shared<MyClass>(10);
          std::cout << "引用计数:" << ptr1.use_count() << std::endl; // 输出:1
      
          // 2. 拷贝,引用计数+1
          std::shared_ptr<MyClass> ptr2 = ptr1;
          std::cout << "引用计数:" << ptr1.use_count() << std::endl; // 输出:2
          std::cout << "引用计数:" << ptr2.use_count() << std::endl; // 输出:2
      
          // 3. 多个指针共享资源
          ptr1->show(); // 输出:值:10
          ptr2->show(); // 输出:值:10
      
          // 4. 重置指针,引用计数-1
          ptr1.reset();
          std::cout << "引用计数:" << ptr2.use_count() << std::endl; // 输出:1
      
          // 5. 管理数组(C++17+支持make_shared数组,C++11/14需手动new)
          std::shared_ptr<int[]> arr_ptr(new int[5]{1,2,3,4,5});
          arr_ptr[1] = 200;
          std::cout << arr_ptr[1] << std::endl; // 输出:200
      
          return 0; // ptr2析构,引用计数变为0,资源释放
      }
      

       关键问题:循环引用

      shared_ptr的最大陷阱是循环引用:两个shared_ptr互相指向对方,导致引用计数永远无法变为 0,最终内存泄漏。

      循环引用示例(错误):

      #include <iostream>
      #include <memory>
      
      class B; // 前向声明
      
      class A {
      public:
          std::shared_ptr<B> b_ptr;
          ~A() { std::cout << "A 析构" << std::endl; }
      };
      
      class B {
      public:
          std::shared_ptr<A> a_ptr;
          ~B() { std::cout << "B 析构" << std::endl; }
      };
      
      int main() {
          std::shared_ptr<A> a = std::make_shared<A>();
          std::shared_ptr<B> b = std::make_shared<B>();
          a->b_ptr = b; // A引用B
          b->a_ptr = a; // B引用A
          // 循环引用:a和b的引用计数都是2,析构时各减1,变为1,永远不会释放
          return 0; // 不会输出"A 析构"和"B 析构",内存泄漏
      }
      

      3. std::weak_ptr(弱引用智能指针)

      特性与使用场景

      • 弱引用:不拥有资源,不增加 shared_ptr 的引用计数,不影响资源释放;
      • 解决循环引用:shared_ptr 循环引用会导致引用计数无法归零,weak_ptr 可打破循环;
      • 不能直接解引用:必须通过 lock() 转为 shared_ptr 后才能访问资源。

      签名(类模板声明)

      template <class T>
      class weak_ptr;
      

      成员函数签名

      // 1. 从shared_ptr构造(不增加引用计数)
      template <class U>
      weak_ptr(const shared_ptr<U>& r) noexcept;
      
      // 2. 锁定为shared_ptr(安全访问资源)
      shared_ptr<T> lock() const noexcept;
      
      // 3. 检查资源是否已释放(过期)
      bool expired() const noexcept;
      
      // 4. 获取对应的shared_ptr引用计数(仅参考,可能瞬时变化)
      long use_count() const noexcept;
      
      // 5. 重置(清空弱引用)
      void reset() noexcept;
      
      部分含义
      template <class T>指向的对象类型与 shared_ptr 一致;
      lock()核心函数:返回一个 shared_ptr(若资源未释放则引用计数 + 1,否则返回空 shared_ptr),是访问弱引用资源的唯一安全方式;
      expired()等价于 use_count() == 0,但更高效(无需获取精确的引用计数值);

        解决循环引用的示例(正确):

        #include <iostream>
        #include <memory>
        
        class B;
        
        class A {
        public:
            std::weak_ptr<B> b_ptr; // 改为weak_ptr
            ~A() { std::cout << "A 析构" << std::endl; }
        };
        
        class B {
        public:
            std::weak_ptr<A> a_ptr; // 改为weak_ptr
            ~B() { std::cout << "B 析构" << std::endl; }
        };
        
        int main() {
            std::shared_ptr<A> a = std::make_shared<A>();
            std::shared_ptr<B> b = std::make_shared<B>();
            a->b_ptr = b; // weak_ptr不增加引用计数
            b->a_ptr = a; // weak_ptr不增加引用计数
        
            // 检查资源是否存在
            if (auto temp = a->b_ptr.lock()) { // lock()返回shared_ptr,若资源存在则有效
                std::cout << "B资源存在" << std::endl;
            }
        
            return 0; // a和b析构,引用计数变为0,资源释放(输出"A 析构"和"B 析构")
        }
        

        关键说明

        • weak_ptr不能直接访问资源(没有->和*运算符),必须通过lock()获取shared_ptr后才能访问;
        • expired()方法可以判断weak_ptr指向的资源是否已释放(返回true表示已释放);
        • weak_ptr的大小和shared_ptr相同(因为要存储引用计数的指针)。

        内存泄漏案例以及改良方案

        内存泄漏的核心本质是:堆内存被分配后,失去了对它的所有引用,导致程序无法再释放这块内存,直到程序退出(系统会回收,但长期运行的程序如服务器会持续占用内存)。

        常见的内存泄漏场景

        1. 最基础:忘记释放手动分配的内存

        这是新手最易犯的错误 —— 用new/malloc分配堆内存后,未调用delete/free释放,尤其是在分支、循环等复杂逻辑中更容易遗漏。

        示例代码(错误):

        #include <iostream>
        using namespace std;
        
        void func() {
            // 分配堆内存
            int* p = new int(10);
            string name = "test";
            // 分支逻辑导致忘记释放
            if (name == "test") {
                cout << "分支返回,遗漏delete" << endl;
                return; // 直接返回,p指向的内存永远无法释放
            }
            // 只有走else才会释放(本例不会执行)
            delete p;
        }
        
        int main() {
            func(); // 执行后内存泄漏(4字节int)
            return 0;
        }
        

        避免方法:

        • 优先使用智能指针(unique_ptr/shared_ptr)替代裸指针;
        • 若必须用裸指针,遵循 “分配即规划释放” 原则,在分配内存时就确定释放的位置。

        修复后的完整代码

        #include <iostream>
        #include <memory>  // 必须包含智能指针的头文件
        using namespace std;
        
        void func() {
            // 用unique_ptr替代裸指针,make_unique是创建unique_ptr的推荐方式
            unique_ptr<int> p = make_unique<int>(10);
            string name = "test";
            
            if (name == "test") {
                cout << "分支返回,智能指针自动释放内存" << endl;
                return; // 即使提前返回,p也会析构并释放内存
            }
            
            // 无需手动delete!智能指针超出作用域时会自动释放
            // 原来的delete p 可以完全删除
        }
        
        int main() {
            func(); // 执行后无内存泄漏
            return 0;
        }

        2. 异常导致的内存泄漏

        new分配内存后,delete执行前抛出异常,导致delete语句无法执行,进而泄漏内存。这是比 “忘记释放” 更隐蔽的问题。

        示例代码(错误):

        #include <iostream>
        #include <stdexcept>
        using namespace std;
        
        void riskyFunc() {
            throw runtime_error("突发异常"); // 抛出异常
        }
        
        void func() {
            int* p = new int(20); // 分配内存
            riskyFunc(); // 抛出异常,后续代码全部跳过
            delete p; // 永远执行不到,内存泄漏
        }
        
        int main() {
            try {
                func();
            } catch (const exception& e) {
                cout << "捕获异常:" << e.what() << endl;
            }
            return 0;
        }
        

        避免方法:

        • 核心方案:使用智能指针(RAII 机制),即使抛出异常,智能指针对象析构时仍会自动释放内存;
        • 兜底方案:用try-catch包裹,但代码冗余且易遗漏,不如智能指针可靠。

        修复后的代码:

        #include <iostream>
        #include <stdexcept>
        #include <memory> // 智能指针头文件
        using namespace std;
        
        void riskyFunc() {
            throw runtime_error("突发异常");
        }
        
        void func() {
            unique_ptr<int> p = make_unique<int>(20); // 智能指针
            riskyFunc(); // 抛异常也不影响,p析构时自动释放
        }
        
        int main() {
            try {
                func();
            } catch (const exception& e) {
                cout << "捕获异常:" << e.what() << endl;
            }
            return 0; // 无内存泄漏
        }
        

        3. shared_ptr 的循环引用(进阶陷阱)

        这是使用智能指针时的高频错误 —— 两个或多个shared_ptr互相持有对方的引用,导致引用计数永远无法归 0,内存无法释放。

        示例代码(错误):

        #include <iostream>
        #include <memory>
        using namespace std;
        
        class B; // 前向声明
        
        class A {
        public:
            shared_ptr<B> b_ptr; // A持有B的shared_ptr
            ~A() { cout << "A 析构" << endl; } // 不会执行
        };
        
        class B {
        public:
            shared_ptr<A> a_ptr; // B持有A的shared_ptr
            ~B() { cout << "B 析构" << endl; } // 不会执行
        };
        
        int main() {
            shared_ptr<A> a = make_shared<A>();
            shared_ptr<B> b = make_shared<B>();
            a->b_ptr = b; // 循环引用开始
            b->a_ptr = a;
            // a和b的引用计数都是2,析构时各减1变为1,永远不会释放
            return 0; // 无析构输出,内存泄漏
        }
        

        避免方法:

        • 将循环引用中的一方或双方的shared_ptr替换为weak_ptr(弱引用,不增加引用计数);
        • 修复后的代码可参考上一轮讲解智能指针时的weak_ptr示例。

        4. 容器存储裸指针未清理

        vector/list/map等容器存储裸指针时,清空容器(如clear())仅会删除指针本身(容器内的元素),但不会释放指针指向的堆内存。

        示例代码(错误):

        #include <iostream>
        #include <vector>
        using namespace std;
        
        int main() {
            vector<int*> vec;
            // 向容器添加堆内存指针
            vec.push_back(new int(1));
            vec.push_back(new int(2));
            vec.push_back(new int(3));
        
            vec.clear(); // 仅清空容器,3个int的堆内存未释放,泄漏
            return 0;
        }
        

        避免方法:

        • 容器中存储智能指针(如vector<unique_ptr<int>>),清空时自动释放内存;
        • 若必须存裸指针,清空容器前遍历 delete 每个元素。

        修复后的代码:

        #include <iostream>
        #include <vector>
        #include <memory>
        using namespace std;
        
        int main() {
            vector<unique_ptr<int>> vec;
            vec.push_back(make_unique<int>(1));
            vec.push_back(make_unique<int>(2));
            vec.push_back(make_unique<int>(3));
        
            vec.clear(); // 自动释放所有堆内存,无泄漏
            return 0;
        }
        

        5. 动态数组释放错误(delete vs delete [])

        用new[]分配的数组,若误用delete(而非delete[])释放:

        • 对于类对象数组:仅调用第一个元素的析构函数,其余元素的析构函数不执行,导致内存泄漏;
        • 对于内置类型数组(int/char 等):看似无泄漏,但属于 “未定义行为”,可能引发其他问题。

        示例代码(错误):

        #include <iostream>
        using namespace std;
        
        class MyClass {
        public:
            MyClass() { cout << "MyClass 构造" << endl; }
            ~MyClass() { cout << "MyClass 析构" << endl; }
        };
        
        int main() {
            // 分配对象数组
            MyClass* arr = new MyClass[3]; // 输出3次构造
            delete arr; // 错误!仅调用第一个对象的析构,后2个泄漏
            // 正确写法:delete[] arr;
            return 0;
        }
        

        避免方法:

        • 严格遵循 “new配delete,new[]配delete[]” 的规则;
        • 优先使用vector或unique_ptr<T[]>管理动态数组(无需手动释放)。

        6. 全局 / 静态指针的内存泄漏

        全局或静态指针指向堆内存时,若程序结束前未释放:

        • 虽然程序退出后操作系统会回收内存,但长期运行的程序(如服务器、后台服务)会持续占用内存,最终导致内存耗尽;
        • 不符合 “资源用完即释放” 的编程规范。

        示例代码(错误):

        #include <iostream>
        using namespace std;
        
        // 全局指针
        int* g_ptr = new int(100);
        
        int main() {
            // 程序运行期间未释放g_ptr,直到退出才被系统回收
            cout << *g_ptr << endl;
            // 遗漏:delete g_ptr;
            return 0;
        }
        

        避免方法:

        • 用全局智能指针(如static unique_ptr<int> g_ptr = make_unique<int>(100));
        • 在程序退出前(如 main 结束前)显式释放全局 / 静态裸指针。

        7. 第三方库资源未释放

        使用第三方库的 API 分配资源(如自定义句柄、内存、句柄)时,未调用库提供的 “释放函数”,导致泄漏(这类泄漏常被忽略)。

        示例场景(伪代码):

        // 第三方库API示例
        void* create_obj(); // 分配资源,返回指针
        void destroy_obj(void* p); // 释放资源
        
        int main() {
            void* obj = create_obj(); // 分配资源
            // 业务逻辑...
            destroy_obj(obj); // 忘记调用,资源泄漏
            return 0;
        }
        

        避免方法:

        • 封装成 RAII 类,析构函数中调用释放函数;
        • 记录所有 “分配 - 释放” API 对,确保成对调用。
        C++智能指针简单剖析 导读最近在补看《C++ Primer Plus》第六版,这的确是本好书,其中关于智能指针的章节解析的非常清晰,一解我以前的多处困惑。C++面试过程中,很多面试官都喜欢问智能指针相关的问题,比如你知道哪些智能指针?shared_ptr的设计原理是什么?如果让你自己设计一个智能指针,你如何完成?等等……。而且在看开源的C++项目时,也能随处看到智能指针的影子。这说明智能指针不仅是面试官爱问的题材,更是 阅读详情

        相关推荐

        AI测试实战:用文心一言5分钟生成登录功能测试用例(附Excel模板)

        本文详细介绍了如何利用AI工具(如文心一言)在5分钟内高效生成登录功能测试用例,并提供了可直接应用的Excel模板。通过对比传统手工编写与AI生成的效率差异,展示了AI在软件测试领域的巨大优势,包括减少重复劳动、避免边界条件遗漏和提升格式标准化。文章还包含实战技巧、高级应用方案和行业最佳实践,助力测试人员快速提升工作效率。

        weixin_30379531的博客 410

        C++-详解智能指针

        RAII)是一种利用对象生命周期来控制程序资源(如内存、文件句柄、网络连接、互斥量等等)的简单技术。在对象构造时获取资源,接着控制对资源的访问使之在对象的生命周期内始终保持有效,最后在对象析构的时候释放资源。借此,我们实际上把管理一份资源的责任托管给了一个对象。这种做法有两大好处:不需要显式地释放资源。采用这种方式,对象所需的资源在其生命期内始终保持有效。

        weixin_52159554的博客 3242

        2021秋-北邮计算机导论期末考试(BUPT)

        2021秋-北邮计算机导论期末考试(BUPT) 难度较低适合新手练习

        weixin_73985779的博客 1494

        C++中的智能指针

        什么是内存泄漏:内存泄漏指因为疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理上的消失,而是应用程序分配某段内存后,因为设计错误,失去了对该段内存的控制,因而造成了内存的浪费。内存泄漏的危害:长期运行的程序出现内存泄漏,影响很大,如操作系统、后台服务等等,出现内存泄漏会导致响应越来越慢,最终卡死。// 1.内存申请了忘记释放// 2.异常安全问题Func();// 这里Func函数抛异常导致 delete[] p3未执行,p3没被释放.int _year;

        2202_75331338的博客 1339

        从SD更新字库到FLASH,再用LCD显示

        用Flash当字库存储载体。思路是先将要用到的字库文件存在SD卡,然后存储到Flash,LCD显示时候从Flash中读取 还挺顺利的,移植的原子的程序,自己稍加修改,主要是我的液晶屏函数,Flash读写函数,还有存储文件的flash地址不一样。一晚上搞定,大小字体都OK。挺高兴哈哈。这几天忙工作事情有点耽搁了学习进展嘿嘿 在text.c的showstr函数中char的字体颜色随意设置的,可以显...

        weixin_30505751的博客 914

        wireshark提取视频数据之RTP包中提取H264和H265

        本文主要描述从wireshark包数据中提取出H264和H265裸流数据方法,裸流通过RTP封包方式发送,从抓包中直接提取视频流数据,进而进行流媒体问题定位

        技术控的笔记 17万+

        cpp智能指针的原理与使用

        智能指针不是指针,是一个管理指针的类,用来存储指向动态分配对象的指针,负责自动释放动态分配的对象,防止堆内存泄漏和空悬指针等等问题。动态分配的资源,交给一个类对象去管理,当类对象声明周期结束时,自动调用析构函数释放资源。智能指针的历史历程:C++ 98 中产生了第一个智能指针auto_ptr。C++boost给出了更加实用的scoped_ptr(防止拷贝) 和 shared_ptr(引进引用计数) 和 weak_ptr。

        菜一头包的博客 1215

        【重温童年】基于tkinter模块设计的Q宠大乐斗武器升星模拟器:重温经典,畅享休闲时光

        与传统的Q宠大乐斗不同,这款模拟器还加入了一个创新的功能——自定义升星概率。玩家可以根据自己的喜好和策略,为不同的武器设置不同的成功率和降级率。比如,你可以将“嗜血”这把武器的升星难度设置得极高,以体现其稀有性和强大威力;也可以将“平底锅”这样的普通武器设置得相对容易升星,让玩家在升级过程中感受到更多的成就感。这种自定义的概率设置,不仅增加了游戏的趣味性和挑战性,还让玩家在升级过程中有了更多的策略和选择。你可以根据自己的武器库和卷轴数量,制定出最合适的升级计划,从而在游戏中占据先机。

        nmdbbzcl的博客 1235

        c++ 智能指针_C++:智能指针是如何实现的

        C++程序运行时,计算机内存从大类上分为栈和堆,在栈上的内存是由系统自动分配和回收的,而堆上的内存却是由程序员手动申请和释放的,如果程序员在内存的管理上出现失误,轻则程序运行结果与预期有差距,重则程序直接崩溃;栈和堆内存回收区别栈内存上的变量在过了作用域(大括号)后系统会自动回收,而堆内存则不会。 class MyClass{public: MyClass(){cout<<"start...

        weixin_39545310的博客 179

        从 Classic ABAP 到 ABAP Cloud:一份面向开发者的 SAP 学习路线图与实战指南

        ABAP技术演进路线:从语法到架构思维 本文系统梳理了现代ABAP开发者的能力成长路径。在S/4HANA与云时代,ABAP已从传统过程式语言转变为支持面向对象、测试驱动和云原生开发的现代技术栈。学习路线应围绕四大核心维度展开:1) 语言基础(ABAP OO/Modern ABAP);2) 工程化实践(ABAP Unit/ATC/Clean ABAP);3) 数据建模(CDS/AMDP);4) 服务化架构(Gateway/OData/Fiori)。文章强调以交付形态倒推技术栈,通过真实案例展示了如何将零散技术

        2007 年 ~ 2025 年,深耕 SAP 技术 18 年 360

        Python在振动信号处理中的应用(一):振动信号消除多项式趋势项

        文章目录一、概述二、最小二乘法去除趋势项原理三、python模块介绍3.1 scikitlearn简介(1)转化器(Transformer)(2)估计器(Estimator)3.2 线性回归LinearRegression3.3 多项式PolynomialFeatures3.4 工作流Pipeline四、python代码实现4.1 构造模拟信号4.2 编写去除趋势项主代码4.3 展示算法效果五、TIPS 一、概述   在振动测试过程中,传感器或采集设备由于自身性能问题或受环境干扰(如温度、供电等影响),容易

        白银时代的博客 8578

        C/C++学习笔记 C++中的智能指针

        在现代 C++ 编程中,标准库包含智能指针,用于帮助确保程序没有内存和资源泄漏,并且是异常安全的。智能指针是一个组合类,旨在管理动态分配的内存并确保在智能指针对象超出范围时删除内存。智能指针只是包装原始指针并重载->and*运算符的类;这允许它们提供与原始指针相同的语法。智能指针在头文件的std命名空间中定义。它们对于RAII(对象生命周期和资源管理)或Resource Acquisition Is Initialization编程习惯至关重要。

        学以致用 知行合一 2778

        华为OD机试双机位C卷 - 比赛 / 评委评分 (C++ & Python & JAVA & JS & GO)

        华为OD机试双机位C卷 比赛,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解。华为OD机试-比赛,华为OD机考-比赛。

        qq_45776114的博客 1700

        C++11智能指针:指针的究极进化

        详细介绍了C++11中智能指针概念使用方法以及原理,介绍了auto_ptr、unique_ptr、shared_ptr的功能使用方法并对其进行模拟实现。

        2201_75880188的博客 1523

        蓝牙模块HM-10手册

        蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

        数学建模模型总结

        这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

        C++之智能指针的学习总结

        一、智能指针的学习:1、内存泄漏:关于内存泄漏这个问题,一般都会牵扯到指针这个话题,也就是我们常说的动态内存分配;然而在程序员手动进行堆空间的分配时(指针无法控制所指堆空间的生命周期,)...

        Dada_ping的博客 266

        复分析 阿尔福斯(Ahlfors) 第三版答案 英文

        答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

        C++ 智能指针详解

        简介 智能指针仅用于存储在堆中分配的内存的对象,智能指针做的工作比原始指针多得多。智能指针最重要的是特性是不必使用delete 和 delete[] 运算符释放内存,只要不再需要智能指针,它们就会自动释放。这样就可以避免多次释放、分配/释放不匹配、指针悬挂和内存泄露的可能性。 智能指针特别适合用于管理动态创建的类对象,但智能指针不能完成原始指针的所有操作,智能指针不能递增或递减,也不能执行其他算术操作。智能指针由标准库memory 头文件中的模版定义,所以必须在源文件中包含这个头文件,才能使用智能指..

        Tyler_Zx的博客 2625

        C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

        基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

        【C++】C++的内存处理 --- 智能指针

        本文探讨了C++智能指针的原理与应用,分析了传统异常机制中内存泄漏问题,并提出智能指针的解决方案。文章详细介绍了RAII技术、shared_ptr、unique_ptr和weak_ptr的使用,并演示了如何通过自定义删除器来适配不同的资源释放需求。同时,文章还提及了多线程环境下智能指针的安全性和内存泄漏问题,强调智能指针在预防内存泄漏中的重要作用,为C++开发者提供了实用的内存管理指南。

        叫我龙翔的博客 1584

        C++智能指针

        C++智能指针是一种用于管理动态分配的内存的特殊类型的指针。智能指针是通过类来实现的,它提供了自动管理内存的功能。C++中常见的智能指针包括std::unique_ptr、std::shared_ptr和std::weak_ptr头文件: #include <memory>c++98智能指针,已在C++11中弃用。auto_ptr具有一些限制和缺陷,例如不能在容器中存储auto_ptr对象,不能进行拷贝操作等,auto_ptr,而是使用更安全和功能更强大的智能指针类如unique_ptr。

        u011486857的专栏 1694

        c++智能指针

        智能指针是一种特殊的类模板,用于管理动态内存资源。它通过封装原始指针,并在其生命周期内自动管理内存释放,从而避免了手动内存管理的复杂性和潜在错误(如内存泄漏、双重释放等)。智能指针的设计基于RAII理念,确保资源在对象生命周期结束时自动释放。在智能指针发展的过程中,C++98的auto_ptr:C++98标准引入了auto_ptr,这是智能指针的早期实现。auto_ptr的设计目的是在对象被销毁时自动删除它所指向的内存。然而,auto_ptr。

        欢迎来到jiantaoyab博客 989

        c++ 智能指针用法详解

        c++ 智能指针用法详解 本文介绍c++里面的四个智能指针: 1、auto_ptr,定义在c++98,在C++11已被弃用 2、shared_ptr, weak_ptr, unique_ptr 这三个是c++11支持的 为什么要使用智能指针:我们知道c++的内存管理是让很多人头疼的事,当我们写一个new语句时,一般就会立即把delete语句直接也写了,但是我们不能避免程序还未执行到delete时就跳转了或者在函数中没有执行到最后的delete语句就返回了,如果我们不在每一个可能跳转或者返回的语句前释

        mabiao0825的博客 1822

        C++中智能指针概念及模拟实现

        什么是智能指针,提出智能指针的目的是什么,智能指针的各版本,及模拟实现。

        w903414的博客 1156

        C++——智能指针

        为什么要使用智能指针? 为了防止程序员遗忘释放指针,使用智能指针可以帮助我们管理内存,防止内存泄漏 智能指针的原理? 一、从较浅的层面看,智能指针是对普通的指针进行了封装,这使得智能指针实质其实是一个对象,只是表现的却像一个指针。 二、由于智能指针是一个类对象,在被调函数执行完,对象将会被删除。同时,它指向的内存也会被删除的因此实现了指针的释放。 三、智能指针重载了->符和=符,重载这两个符...

        New_User_Ling的博客 662

        C++ 11 智能指针

        C++ 11 智能指针分析

        阿呆的隐秘角落 338
        上一篇: Linux_C++_日志实例
        下一篇: C++ 运算符重载
        Howrun777
        博客等级 码龄1年 133粉丝 100原创
        评论
        成就一亿技术人!
        拼手气红包6.0元
        还能输入1000个字符
         
         条评论被折叠 查看
        添加红包

        请填写红包祝福语或标题

        个

        红包个数最小为10个

        元

        红包金额最低5元

        当前余额3.43元 前往充值 >
        需支付:10.00元
        成就一亿技术人!
        领取后你会自动成为博主和红包主的粉丝 规则
        hope_wisdom
        发出的红包
        实付元
        使用余额支付
        点击重新获取
        扫码支付
        钱包余额 0

        抵扣说明:

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

        余额充值