电脑维修网站模板推广链接网站

当前位置: 首页 > news >正文

电脑维修网站模板,推广链接网站,软件开发是学什么,做网页怎么建站点前言 nav2系列教材#xff0c;yolov11部署,系统迁移教程我会放到年后一起更新#xff0c;最近年末手头事情多#xff0c;还请大家多多谅解。 上一节我们讲述了C移动语义相关的知识#xff0c;本期我们来看看C中常用的几种智能指针#xff0c;并看看他们在设计模式中的运…前言 nav2系列教材yolov11部署,系统迁移教程我会放到年后一起更新最近年末手头事情多还请大家多多谅解。 上一节我们讲述了C移动语义相关的知识本期我们来看看C中常用的几种智能指针并看看他们在设计模式中的运用。 【C移动语义与完美转发】左值右值引用引用折叠移动语义万能引用与完美转发 1 RAII RAIIResource Acquisition Is Initialization是一种广泛应用于 C 中的编程范式特别是在资源管理和内存管理方面。RAII 的核心思想是资源的获取和释放与对象的生命周期绑定。资源的获取如内存、文件句柄、网络连接等通过构造函数完成而资源的释放则通过析构函数完成。 1-1 RAII 的基本概念 在 RAII 模式中资源管理由对象的生命周期来控制。对象在创建时获取资源在销毁时释放资源。这种方式有两个主要的好处 自动释放资源对象的析构函数会自动释放资源确保不会忘记释放。异常安全由于析构函数会在对象生命周期结束时自动调用它确保了即使发生异常资源也能正确释放。
1-2 RAII 的工作原理 RAII 依赖于对象的构造和析构过程来管理资源具体工作流程如下 资源获取Acquisition 在对象的构造函数中获取资源。比如打开一个文件、分配内存、获取数据库连接等。 资源释放Release 在对象的析构函数中释放资源。这样当对象生命周期结束时资源会自动被释放。
1-3 RAII 的优势 RAII 模式的最大优势就是自动管理资源。你不需要显式地调用资源释放函数如 delete 或 close()而是让 C 的对象生命周期来管理资源。C 中的异常机制意味着代码在执行过程中可能会抛出异常。如果不小心在抛出异常之前忘记释放资源可能会导致资源泄漏。RAII 模式通过将资源释放绑定到对象的析构函数来确保在任何情况下包括异常发生时资源都会被释放。RAII 使得资源的管理更为简洁。你不需要显式调用释放资源的代码只需要关注对象的生命周期编译器和 C 标准库会自动处理资源的释放。 而常见RAII的例子就是智能指针。 2 智能指针 2-1 介绍 正如cppreference提到的智能指针可以实现自动的、异常安全的、对象生命周期管理。在C中智能指针Smart Pointers是C标准库提供的一种机制用于自动管理动态分配的内存减少内存泄漏和悬挂指针等问题。智能指针通过封装原始指针提供了内存管理的自动化机制即使程序员没有显式地调用 delete 来释放内存智能指针也能保证内存最终会被正确释放。![[Pasted image 20241221100154.png]]在 C11 中确实引入了一些智能指针类型来帮助管理对象的生命周期减少内存泄漏和悬挂指针等问题。 std::unique_ptr — 引入于 C11提供唯一所有权语义。std::shared_ptr — 引入于 C11提供共享所有权语义。std::weak_ptr — 引入于 C11用于解决 std::shared_ptr 之间的循环引用问题。std::auto_ptr — 在 C98 中引入在 C11 中被废弃并在 C17 中移除。(本文不讲)
2-2 智能指针前置知识decltype 这一小节我们会补充一些C冷知识decltype 是 C11 引入的关键字用于获取一个表达式的类型或者说是推导某个对象、变量、表达式的类型。它非常强大可以在编译时自动推导出类型常用于模板编程或者自动推导复杂类型的场景。decltype 的基本语法 expression可以是任何表达式比如变量、函数调用、类型、运算结果等。
decltype(expression)decltype 的作用 推导类型decltype 根据一个给定的表达式来推导出其类型。 int a10; decltype(a) ba;与 auto 配合使用decltype 可以与 auto 搭配使用用于推导复杂表达式的类型。 auto x 10; // auto 推导出 x 的类型是 int decltype(x) y 20; // y 的类型也是 int获取函数返回类型decltype 可以用于获取函数的返回类型特别是在模板中或者使用 auto 时decltype 可以帮助我们推导出正确的类型。 templatetypename T,typename U auto add(const T a,const Ub)-decltype(ab) {return ab; }上述代码你可以会发现,即使不加decltype(ab),auto也能正确地推倒出函数的正确类型,那么我们来看看下面的例子: #include iostream #include vector #include type_traitstemplate typename T auto getElementAtIndex(const T container, size_t index) {return container[index]; // 默认返回值是值类型 }template typename T auto getElementAtIndexRef(T container, size_t index) - decltype(container[index]) {return container[index]; // 返回容器中元素的引用 }int main() {std::vectorint vec {10, 20, 30};auto element getElementAtIndex(vec, 1); // 返回的是值类型element150;std::cout vec[1]: vec[1] \n; // 20auto elementRef getElementAtIndexRef(vec, 1); // 返回的是引用类型elementRef 100; std::cout vec[1]: vec[1] \n; // 100return 0; } 可以看到decltype(container[index]) 指定为对应元素的引用类型 3 std::unique_ptr唯一所有权语义 3-1 基础语法 std::unique_ptr 是 C11 引入的智能指针它提供了独占式所有权的语义。也就是说某个对象只能由一个 std::unique_ptr 拥有且不能被拷贝只能被转移。std::unique_ptr 是一种非常轻量的智能指针适用于管理独占资源。特性 唯一所有权std::unique_ptr 在任何时候只能有一个指针持有对象的所有权。如果你尝试复制一个 std::unique_ptr会导致编译错误。你只能通过 std::move 来转移所有权。自动释放资源std::unique_ptr 会在超出作用域时自动释放所管理的对象。它的析构函数会调用对象的删除器默认使用 delete。不可复制std::unique_ptr 不支持拷贝构造和拷贝赋值但支持移动构造和移动赋值。支持自定义删除器可以为 std::unique_ptr 提供自定义删除器指定如何释放所管理的对象。例如可以使用文件关闭函数或自定义的内存释放策略。 基础语法: 备注:std::make_unique需要C14,且std::make_unique 是推荐的创建 unique_ptr 的方法避免了直接使用 new 带来的潜在问题。(不推荐)如果非要使用C11,你可以使用std::unique_ptrT(new T(…))
#include memory class MyClass{}; std::unique_ptrMyClass ptrstd::make_uniqueMyClass();3-2 特性分析 移动语义 std::unique_ptr 不支持复制但支持移动 std::unique_ptrMyClass ptr1 std::make_uniqueMyClass(); std::unique_ptrMyClass ptr2 std::move(ptr1); // 转移所有权 // ptr1 现在是空指针不能再使用释放和重置 reset() 可以释放当前所管理的对象并且可以重新赋值新的对象 ptr1.reset(); // 释放当前管理的对象 ptr1 std::make_uniqueMyClass(); // 重新分配新对象release() 可以获取当前管理的对象指针并释放所有权 MyClass* raw_ptr ptr1.release(); // 获取裸指针且ptr1不再管理该对象管理数组 std::unique_ptr 也可以用于管理动态数组 std::unique_ptrMyClass[] arr std::make_uniqueMyClass; // 管理一个长度为10的数组访问管理对象 使用 get() 获取裸指针使用 * 和 - 操作符访问对象 std::unique_ptrMyClass ptrstd::make_uniqueMyClass(); MyClass* myclassptr.get();ptr-doSomething(); // 使用 - 访问成员 (*ptr).doSomething(); // 使用 * 访问成员3-3 自定义删除器 std::unique_ptr 支持自定义删除器可以传递一个函数、lambda 或者函数对象来管理资源的释放 auto deleter { std::cout Deleting MyClass\n; delete ptr; }; std::unique_ptrMyClass, decltype(deleter) ptr(new MyClass(), deleter); 自定义删除器 和 reset() 函数的区别: 特性自定义删除器reset() 方法目的控制资源的释放方式不仅限于 delete手动释放当前对象并可重新分配新对象使用场景需要自定义释放逻辑例如文件关闭、内存管理等简单地手动释放资源或替换当前管理的对象灵活性非常灵活可以传入任何符合要求的删除器限制较少简单但不支持额外的清理工作适用情况需要自定义删除行为或清理逻辑只需要释放当前对象或重置 unique_ptr 为新对象 这样我们就可以实现自动释放执行我们的自定义删除器了实际运用中我们可以使用函数对象function object来封装自定义删除器 #include iostream #include memorytemplatetypename T struct CustonDeleter {void operator()(T* ptr)const{// 进行额外的处理std::coutCustonDeleter callstd::endl;delete ptr;} }; class MyClass { public:MyClass(){std::coutMyClass()std::endl;}~MyClass(){std::cout~MyClass()std::endl;}};int main() {std::unique_ptrMyClass,CustonDeleterMyClassptr(new MyClass());return 0; }3-4 std::unqiue_ptr在多态的使用 代码如下 #include iostream #include memoryclass Base { public:Base(){}virtual ~Base(){}virtual void run()0;}; class A :public Base { public:A(){std::coutA()std::endl;}~A(){std::cout~A()std::endl;}void run()override {std::coutA run()std::endl;} }; class B :public Base { public:B(){std::coutB()std::endl;}~B(){std::cout~B()std::endl;}void run()override{std::coutB run()std::endl;} }; int main() {std::unique_ptrBase ptrstd::make_uniqueA();ptr-run();ptr.reset();ptrstd::make_uniqueB();ptr-run();std::unique_ptrBase ptr2std::move(ptr);ptr2-run();return 0; }输出 这样可以确保指针所拥有的对象不被拷贝。 4 std::shared_ptr共享所有权语义 4-1 基础语法 std::shared_ptr 是 C11 引入的智能指针它提供了共享所有权的语义。多个 std::shared_ptr 可以指向同一个对象并且会通过引用计数来管理该对象的生命周期。当最后一个指向该对象的 shared_ptr 被销毁时内存会被自动释放。 特性 共享所有权多个 shared_ptr 可以共享对同一个对象的所有权。引用计数每个 std::shared_ptr 都有一个引用计数用来记录有多少个 shared_ptr 实例指向同一个对象。只有当最后一个引用被销毁时才会删除该对象。自动内存管理当最后一个 shared_ptr 被销毁时自动释放资源。
基础语法 use_count()会返回引用计数
#include memory std::shared_ptrMyClassptrstd::make_sharedMyClass(); std::coutptr.use_count():ptr.use_count()std::endl;4-2 特性分析 引用计数与析构std::shared_ptr 使用引用计数来追踪有多少个 shared_ptr 对象共同拥有一个对象。当最后一个 shared_ptr 被销毁时所管理的对象会自动析构。 std::shared_ptrMyClass ptr1 std::make_sharedMyClass(); std::shared_ptrMyClass ptr2 ptr1; // 引用计数变为 2 ptr1.reset(); // 引用计数减少到 1ptr2 仍然拥有对象访问管理的对象:使用 get() 方法可以获取裸指针并且可以使用 * 和 - 操作符来访问所管理的对象 std::shared_ptrMyClass ptr std::make_sharedMyClass(); MyClass* raw_ptr ptr.get(); // 获取裸指针ptr-doSomething(); // 使用 - 访问成员 (*ptr).doSomething(); // 使用 * 访问成员自定义删除器:std::shared_ptr 允许在创建时指定一个自定义的删除器这个删除器会在最后一个 shared_ptr 被销毁时调用以释放资源。 auto deleter {std::cout Deleting MyClass\n;delete ptr; };std::shared_ptrMyClass ptr(new MyClass(), deleter); 4-3 std::enable_shared_from_this std::enable_shared_from_this 是一个帮助类模板允许对象获得指向自身的 shared_ptr。通常类的成员函数可以通过 shared_from_this() 方法返回 shared_ptr从而确保它在成员函数中正确地共享所有权。 #include iostream #include memoryclass MyClass : public std::enable_shared_from_thisMyClass { public:MyClass() { std::cout MyClass constructed\n; }~MyClass() { std::cout MyClass destructed\n; }void show() { std::cout MyClass::show() called\n; }// 返回一个指向当前对象的 shared_ptrstd::shared_ptrMyClass getPtr() {return shared_from_this();} };int main() {std::shared_ptrMyClass ptr1 std::make_sharedMyClass();std::shared_ptrMyClass ptr2 ptr1-getPtr();ptr2-show();std::cout Use count: ptr1.use_count() \n;return 0; } 4-4 std::shared_ptr 之间的循环引用问题 std::shared_ptr 是一种智能指针通过引用计数的方式管理对象的生命周期。当一个 std::shared_ptr 对象被复制或赋值时引用计数增加直到没有任何 std::shared_ptr 持有对象时才会删除对象。然而在某些情况下当多个 std::shared_ptr 相互引用时可能会出现循环引用问题导致内存泄漏。明白多线程死锁的朋友们可以更理解这是啥 【C并发入门】摄像头帧率计算和多线程相机读取上并发基础概念和代码实现 我们来看看这段代码
#include iostream #include memoryclass A; class B;class A { public:std::shared_ptrB b_ptr; // A 持有 B 的 shared_ptr~A() { std::cout A destroyed\n; } };class B { public:std::shared_ptrA a_ptr; // B 持有 A 的 shared_ptr~B() { std::cout B destroyed\n; } };int main() {// 创建 A 和 B 的 shared_ptr并互相持有对方std::shared_ptrA a std::make_sharedA();std::shared_ptrB b std::make_sharedB();a-b_ptr b; // A 持有 Bb-a_ptr a; // B 持有 A// 退出作用域时a 和 b 都不再使用但由于循环引用对象没有被销毁return 0; } 可以看到程序执行后没有任何输出。这是因为 A 和 B 之间相互持有对方的 std::shared_ptr导致引用计数永远不为零。 5 std::weak_ptr 解决 std::shared_ptr 之间的循环引用问题。 5-1 基础语法 std::weak_ptr 是 C11 引入的智能指针用来解决 std::shared_ptr 之间可能产生的循环引用问题。weak_ptr 不增加引用计数它是对由 std::shared_ptr 管理的对象的弱引用。当 shared_ptr 对象被销毁时weak_ptr 不会影响引用计数。 特性 临时所有权std::weak_ptr 模拟了临时所有权。对象可以被访问但如果对象被销毁std::weak_ptr 仍然不持有对对象的所有权并且不增加引用计数。只有在将 std::weak_ptr 转换为 std::shared_ptr 时才能获得对象的所有权并且此时对象的生命周期会延长直到该 shared_ptr 被销毁。打破循环引用std::weak_ptr 是避免由 std::shared_ptr 引起的循环引用问题的常用方式。循环引用是由于对象相互持有 shared_ptr使得引用计数永远不为零从而导致内存泄漏。通过将其中一个对象的 shared_ptr 转为 weak_ptr可以打破这种循环避免内存泄漏。
基础语法 std::shared_ptrint sp std::make_sharedint(10); std::weak_ptrint wp(sp); // 创建一个 weak_ptr指向 shared_ptr 管理的对象5-2 特性 lock()lock() 函数返回一个 std::shared_ptr它可以安全地访问 weak_ptr 引用的对象。如果原始 std::shared_ptr 已被销毁lock() 会返回一个空的 shared_ptr。 std::shared_ptrint sp std::make_sharedint(10); std::weak_ptrint wp sp; std::shared_ptrint spt wp.lock(); // 获取 shared_ptrif (spt) {std::cout Object value: *spt std::endl; } else {std::cout Object expired. std::endl; } use_count():use_count() 返回当前有多少个 std::shared_ptr 管理该对象的引用。注意std::weak_ptr 不会增加引用计数。 std::cout use_count() wp.use_count() std::endl; // 输出引用计数 expired():expired() 函数返回一个布尔值表示 std::weak_ptr 所引用的对象是否已经被销毁即对应的 std::shared_ptr 已经被销毁。 if (wp.expired()) {std::cout The object has been destroyed. std::endl; } else {std::cout The object is still alive. std::endl; } reset()reset() 可以清除 std::weak_ptr 对对象的引用。 wp.reset(); // 重置 weak_ptr释放引用5-3 解决 std::shared_ptr 之间的循环引用问题。 我们看看刚才那个代码 #include iostream #include memoryclass A; class B;class A { public:std::weak_ptrB b_ptr; // A 持有 B 的 weak_ptr避免循环引用~A() { std::cout A destroyed\n; } };class B { public:std::shared_ptrA a_ptr; // B 持有 A 的 shared_ptr~B() { std::cout B destroyed\n; } };int main() {// 创建 A 和 B 的 shared_ptr并互相持有对方std::shared_ptrA a std::make_sharedA();std::shared_ptrB b std::make_sharedB();a-b_ptr b; // A 持有 Bb-a_ptr a; // B 持有 A// 退出作用域时a 和 b 都会被销毁return 0; } 上述修改后的代码A 和 B 之间通过 std::shared_ptr 互相持有对方。为了避免循环引用我们将 A 中的 B 指针改为 std::weak_ptrB。这样A 对 B 的引用不会增加 B 的引用计数从而打破了循环引用。当作用域结束时A 和 B 都会被正确销毁。
5-4 std::weak_ptr 和 std::shared_ptr 的协作 std::weak_ptr 的使用场景通常是与 std::shared_ptr 配合。你可以通过 std::weak_ptr 来观察一个由 std::shared_ptr 管理的对象并且在需要时通过调用 lock() 来获得 shared_ptr确保对象的生命周期被正确延长直到临时的 shared_ptr 被销毁。 #include iostream #include memorystd::weak_ptrint gw; // 定义一个 weak_ptrvoid observe() {std::cout gw.use_count() gw.use_count() ; ;if (auto spt gw.lock()) { // 使用 lock() 获得 shared_ptrstd::cout *spt spt \n;} else {std::cout gw is expired\n;} }int main() {{auto sp std::make_sharedint(42); // 创建 shared_ptrgw sp; // 将 shared_ptr 转换为 weak_ptrobserve(); // 调用 observe 函数输出对象的值}observe(); // 再次调用 observe检查 weak_ptr 是否有效 } 6 智能指针和设计模式 6-1 设计模式 设计模式Design Patterns是软件设计领域中一套通用的、被反复验证的解决方案用于解决软件开发中常见的问题。设计模式提供了一些经过验证的、优雅的代码结构帮助开发者在面对某些重复问题时能够采用一种标准化的解决方案从而提高代码的可维护性、可扩展性和可重用性。设计模式分为 创建型、结构型 和 行为型 三大类每一类中都包含了一些常见的模式。 6-1单例模式Singleton Pattern与智能指针 单例模式旨在确保某个类只有一个实例并提供全局访问点。在 C 中使用智能指针特别是 std::unique_ptr来实现单例模式可以避免手动管理对象生命周期确保对象的销毁由智能指针自动处理。 #include iostream #include memoryclass Singleton { private:static std::unique_ptrSingleton instance;// 私有化构造函数防止外部创建对象Singleton() { std::cout Singleton instance created! std::endl; }public:// 禁用拷贝构造和赋值操作Singleton(const Singleton) delete;Singleton operator(const Singleton) delete;// 获取单例实例static Singleton getInstance() {if (!instance) {instance std::make_uniqueSingleton();}return instance.get();}void showMessage() {std::cout Hello from Singleton! std::endl;} };// 静态成员初始化 std::unique_ptrSingleton Singleton::instance nullptr;int main() {Singleton::getInstance()-showMessage();return 0; } 使用 std::unique_ptr 管理单例对象的生命周期确保在程序结束时单例对象会自动销毁。getInstance() 方法使用懒加载Lazy Initialization方式只有在需要时才创建单例对象。 6-3 工厂方法模式Factory Method Pattern与智能指针 工厂方法模式定义了一个创建对象的接口但由子类决定实例化哪个类。使用智能指针特别是 std::unique_ptr 或 std::shared_ptr可以管理对象的生命周期同时避免了内存泄漏问题。 #include iostream #include memory// 产品接口 class Product { public:virtual void use() 0;virtual ~Product() default; };// 具体产品 class ConcreteProductA : public Product { public:void use() override {std::cout Using ConcreteProductA std::endl;} };class ConcreteProductB : public Product { public:void use() override {std::cout Using ConcreteProductB std::endl;} };// 工厂基类 class Creator { public:virtual std::unique_ptrProduct factoryMethod() 0;virtual ~Creator() default; };// 具体工厂 class ConcreteCreatorA : public Creator { public:std::unique_ptrProduct factoryMethod() override {return std::make_uniqueConcreteProductA();} };class ConcreteCreatorB : public Creator { public:std::unique_ptrProduct factoryMethod() override {return std::make_uniqueConcreteProductB();} };int main() {std::unique_ptrCreator creatorA std::make_uniqueConcreteCreatorA();std::unique_ptrProduct productA creatorA-factoryMethod();productA-use();std::unique_ptrCreator creatorB std::make_uniqueConcreteCreatorB();std::unique_ptrProduct productB creatorB-factoryMethod();productB-use();return 0; } 使用 std::unique_ptr 来确保工厂方法返回的对象的生命周期得到了妥善管理无需手动删除。 在创建对象时工厂方法会返回一个智能指针从而保证了内存的自动释放。 6-4 观察者模式Observer Pattern与智能指针 观察者模式允许一个对象被观察者通知多个依赖对象观察者状态的变化。使用 std::shared_ptr 可以确保观察者对象在多个观察者之间共享并且通过引用计数管理生命周期。 #include iostream #include vector #include memory// 抽象观察者 class Observer { public:virtual void update(int value) 0;virtual ~Observer() default; };// 被观察者 class Subject { private:std::vectorstd::shared_ptrObserver observers;public:void addObserver(const std::shared_ptrObserver observer) {observers.push_back(observer);}void removeObserver(const std::shared_ptrObserver observer) {observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());}void notifyObservers(int value) {for (auto observer : observers) {observer-update(value);}} };// 具体观察者 class ConcreteObserver : public Observer { private:std::string name;public:ConcreteObserver(const std::string name) : name(name) {}void update(int value) override {std::cout Observer name received value: value std::endl;} };int main() {Subject subject;// 创建观察者auto observer1 std::make_sharedConcreteObserver(A);auto observer2 std::make_sharedConcreteObserver(B);subject.addObserver(observer1);subject.addObserver(observer2);// 通知观察者subject.notifyObservers(42);return 0; } 观察者使用 std::shared_ptr 管理确保所有观察者对象的生命周期由引用计数自动管理。当观察者被移除时std::shared_ptr 会自动销毁对象避免内存泄漏。 6-5 策略模式Strategy Pattern与智能指针 策略模式允许在运行时选择算法或行为。使用智能指针如 std::shared_ptr 或 std::unique_ptr可以简化策略对象的创建和管理避免手动内存管理。 #include iostream #include memory// 策略接口 class Strategy { public:virtual void execute() const 0;virtual ~Strategy() default; };// 具体策略A class ConcreteStrategyA : public Strategy { public:void execute() const override {std::cout Executing Strategy A std::endl;} };// 具体策略B class ConcreteStrategyB : public Strategy { public:void execute() const override {std::cout Executing Strategy B std::endl;} };// 上下文类 class Context { private:std::shared_ptrStrategy strategy;public:void setStrategy(const std::shared_ptrStrategy newStrategy) {strategy newStrategy;}void executeStrategy() {if (strategy) {strategy-execute();}} };int main() {Context context;// 使用策略Acontext.setStrategy(std::make_sharedConcreteStrategyA());context.executeStrategy();// 使用策略Bcontext.setStrategy(std::make_sharedConcreteStrategyB());context.executeStrategy();return 0; } 策略对象通过 std::shared_ptr 管理确保不同策略的生命周期由智能指针自动控制。在不同的策略之间切换时智能指针确保不需要手动管理内存。 6-6代理模式Proxy Pattern与智能指针 代理模式为其他对象提供一个代理对象以控制对实际对象的访问。智能指针可以帮助管理代理对象和实际对象的生命周期确保资源的正确释放。 #include iostream #include memory// 抽象Subject class Subject { public:virtual void request() 0;virtual ~Subject() default; };// 具体Subject class RealSubject : public Subject { public:void request() override {std::cout RealSubject request std::endl;} };// 代理类 class Proxy : public Subject { private:std::shared_ptrRealSubject realSubject;public:Proxy(std::shared_ptrRealSubject realSubject) : realSubject(realSubject) {}void request() override {std::cout Proxy forwarding request to RealSubject std::endl;realSubject-request();} };int main() {auto realSubject std::make_sharedRealSubject();Proxy proxy(realSubject);proxy.request();return 0; } std::shared_ptr 用于管理 RealSubject 的生命周期确保它在 Proxy 使用时依然有效并在不再需要时自动销毁。代理类 Proxy 可以控制对实际对象的访问比如增加日志、访问控制等功能。 7 总结 RAII 是 C 中一项非常重要的编程理念尤其适用于资源管理、内存管理以及多线程编程。在 C11 及之后的版本中智能指针如 std::unique_ptr, std::shared_ptr, 和 std::weak_ptr为RAII 模式提供了强大的支持能够自动管理资源确保资源在对象生命周期结束时得到正确释放。 RAII 的优点通过绑定资源的获取与释放到对象的生命周期简化了资源管理减少了错误发生的可能增强了异常安全性。智能指针的优势通过 std::unique_ptr, std::shared_ptr, std::weak_ptr 等智能指针C 提供了自动化的内存管理避免了常见的内存泄漏和悬挂指针问题。RAII 与异常安全RAII 使得在发生异常时资源能够被正确地释放从而保证程序的稳定性。 如有错误欢迎指出感谢大家的支持