首页app攻略c++怎么写类 c++如何用类建立指针

c++怎么写类 c++如何用类建立指针

圆圆2025-06-19 23:01:10次浏览条评论

c智能指针通过raii机制自动管理内存,避免内存溢出。1. unique_ptr实现独占式地址,保证同一时间只有一个指针指向对象,支持显着式转移地址,适用于资源管理和工厂函数返回值;2. shared_ptr采用引用计数实现共享共享,最后一个shared_ptr思考时释放对象,适合多指针共享资源的场景,并可结合weak_ptr解决循环引用;3. weak_ptr提供弱引用,不增加引用统计,用于观察对象状态或打破shared_ptr间的循环引用;4. 推荐使用make_shared创建shared_ptr,提升异常安全性和性能;5. 多线程环境下shared_ptr线程安全但对象访问需要同步,unique_ptr非线程安全;6. 自定义删除器可用于释放非内存资源或特定执行清理操作;7. 选择智能指针时需权衡硬盘模型、性能及线程安全等因素,慎用与原始指针的交互广东重复释放或悬挂指针问题。

C++怎么使用智能指针 C++智能指针的类型与使用场景

C智能指针本质上是为了更好地管理动态分配的内存,避免内存泄漏。它们通过RAII(资源获取是初始化)机制,在对象生命周期结束时自动释放资源。

unique_ptr、shared_ptr、weak_ptr

unique_ptr

立即学习“C免费学习笔记(研究)”;

unique_ptr是独占式指针,意味着同一时间只能有一个unique_ptr指向特定的对象。它的量非常轻,级头几乎与原始相同指针,并且保证了对象线索的唯一性。

#include lt;iostreamgt;#include lt;memorygt;class MyClass {public: MyClass() { std::cout lt;lt; quot;MyClass 构造\nquot;; } ~MyClass() { std::cout lt;lt; quot;MyClass 析构\nquot;; } void doSomething() { std::cout lt;lt; quot;Doing something...\nquot;; }};int main() { std::unique_ptrlt;MyClassgt; ptr(new MyClass()); // 创建 unique_ptr ptr-gt;doSomething(); // 使用 -gt; 访问对象成员 // std::unique_ptrlt;MyClassgt; ptr2 = ptr; // 错误!不能复制 unique_ptr std::unique_ptrlt;MyClassgt; ptr2 = std::move(ptr); // 转移正确的线索 if (ptr) { ptr-gt;doSomething(); // 不会执行,因为 ptr 已经为空 } if (ptr2) { ptr2-gt;doSomething(); // ptr2 现在拥有对象 } return 0; // ptr2 解析结构,MyClass 对象被接口}登录后复制

unique_ptr 的主要:资源管理:用途确定动态分配的对象在不再需要时被自动释放。约会转移:通过std::移动显式地转移。工厂函数:用于从工厂函数返回分配的对象。

shared_ptr

shared_ptr允许多个指针指向同一个对象,它使用引用计数来跟踪有多少个shared_ptr指向该对象。当最后一个shared_ptr被讨论时,对象才会被释放。

#include lt;iostreamgt;#include lt;memorygt;class MyClass {public: MyClass() { std::cout lt;lt; quot;MyClass 已构造\nquot;; } ~MyClass() { std::cout lt;lt; quot;MyClass 已析构\nquot;; } void doSomething() { std::cout lt;lt; quot;正在执行某事...\nquot;; }};int main() { std::shared_ptrlt;MyClassgt; ptr1 = std::make_sharedlt;MyClassgt;(); // 推荐使用 make_shared std::shared_ptrlt;MyClassgt; ptr2 = ptr1; // 共享 std::cout lt;lt; quot;ptr1 use count: quot; lt;lt; ptr1.use_count() lt;lt; std::endl; // 输出 2 std::cout lt;lt; quot;ptr2 use count: quot; lt;lt; ptr2.use_count() lt;lt; std::endl; // 输出 2 ptr1-gt;doSomething(); ptr2-gt;doSomething(); ptr1.reset(); // 释放 ptr1 的循环 std::cout lt;lt; quot;ptr1 use count: quot; lt;lt; ptr1.use_count() lt;lt; std::endl; // 输出 0 std::cout lt;lt; quot;ptr2 use count: quot; lt;lt; ptr2.use_count() lt;lt; std::endl; // 输出 1 return 0; // ptr2 解析结构,MyClass 对象被调用}登录后复制

shared_ptr的主要用途:共享共享:当多个对象需要共享对一个资源的共享时。循环引用处理:与weak_ptr结合使用,打破循环引用。在多线程环境中安全地共享资源。

weak_ptr

weak_ptr是一种弱引用,它指向由shared_ptr管理的对象,但不增加引用计数。weak_ptr不能直接访问对象,必须先转换为shared_ptr才能使用。当shared_ptr管理的对象被外部时,weak_ptr会自动作用。

#include lt;iostreamgt;#include lt;memorygt;class MyClass {public: MyClass() { std::cout lt;lt; quot;MyClass 已构造\nquot;; } ~MyClass() { std::cout lt;lt; quot;MyClass 已析构\nquot;; } void doSomething() { std::cout lt;lt; quot;正在执行某事...\nquot;; }};int main() { std::shared_ptrlt;MyClassgt; sharedPtr = std::make_sharedlt;MyClassgt;(); std::weak_ptrlt;MyClassgt; weakPtr = sharedPtr; if (auto ptr = weakPtr.lock()) { // 尝试获取 shared_ptr ptr-gt;doSomething(); // 不包括访问对象 std::cout lt;lt; quot;对象仍然alive\nquot;; } else { std::cout lt;lt; quot;对象已被销毁\nquot;; } sharedPtr.reset(); // 释放shared_ptr的循环 if (auto ptr =weakPtr.lock()) { ptr-gt;doSomething(); // 不会执行 std::cout lt;lt; quot;对象还活着\nquot;; } else { std::cout lt;lt; quot;对象已被销毁\nquot;; // 此输出行 } return 0;}登录后复制

weak_ptr的主要用途:观察者模式:允许观察对象的状态,而不影响对象的生命周期。 缓存: 缓存对象,当对象不再被使用时自动释放。解决shared_ptr可能导致的循环引用问题。

如何选择合适的智能指针?

在选择智能指针时,需要考虑以下因素:艾滋病模型: 性能: unique_ptr 增加,shared_ptr 增加。 线程安全:shared_ptr 是线程安全的,unique_ptr 不是。 循环引用:是否需要循环引用问题?

为什么推荐使用make_shared?

std::make_shared是一个模板函数,用于创建一个shared_ptr并初始化其指向的对象。与先new再使用shared_ptr包装相比,make_shared的主要优势在于:异常安全:如果new操作成功,但在shared_ptr构造函数中初始化异常,会导致内存流出。

make_shared将对象的分配内存和shared_ptr的构造在一起,避免了这个问题。性能优化:make_shared通常会一次性分配对象和shared_ptr控制块的内存,减少内存分配次数,提高性能。

智能指针与原始指针的混合使用问题

虽然智能指针旨在替代原始指针,但在某些情况下,仍然需要与原始指针移植,例如:与旧代码库集成:旧代码库可能使用原始指针,需要将智能指针转换为原始指针进行交互。底层操作:某些底层操作可能需要直接访问内存地址。

在与原始指针交互出现时,请小心,避免以下问题:重复释放:不要使用原始指针删除由需要智能指针管理的对象。 当智能指针释放对象后,原始指针可能变成悬浮指针。

可以使用get()方法从智能指针获取原始指针,但必须严格使用,并保证在使用原始指针时,智能指针仍然有效。

如何避免循环?

循环引用是指两个或多个对象互相持有shared_ptr,导致引用计数永远不清晰,对象无法被释放。

例如:#include lt;iostreamgt;#include lt;memorygt;class A; // 向前声明class B {public: std::shared_ptrlt;Agt; a; ~B() { std::cout lt;lt; quot;B destructed\nquot;; }};class A {public: std::shared_ptrlt;Bgt; b; ~A() { std::cout lt;lt; quot;A destructed\nquot;; }};int 主要的() { std::shared_ptrlt;Agt; a = std::make_sharedlt;Agt;(); std::shared_ptrlt;Bgt; b = std::make_sharedlt;Bgt;(); a-gt;b = b; b-gt;a = a; // 循环引用 // a 和 b 都不会被内部,导致内存泄漏返回0;}登录后复制

解决循环引用的常用方法是使用weak_ptr。将其中一个shared_ptr改为weak_ptr,打破循环引用。

#include lt;iostreamgt;#include lt;memorygt;class A; // 前向声明class B {public: std::weak_ptrlt;Agt; a; // 使用weak_ptr ~B() { std::cout lt;lt; quot;B destructed\nquot;; }};class A {public: std::shared_ptrlt;Bgt; b; ~A() { std::cout lt;lt; lt; quot;A destructed\nquot;; }};int main() { std::shared_ptrlt;Agt; a = std::make_sharedlt;Agt;(); std::shared_ptrlt;Bgt; b = std::make_sharedlt;Bgt;(); a-gt;b = b; b-gt;a = a; // 循环引用被打破 // a 和 b 都会被返回0;}登录后复制

智能指针在多线程环境下的使用

shared_ptr修改本身是线程安全的,多个线程可以同时访问和同一个shared_ptr对象,而不会导致数据竞争但是,shared_ptr指向的对象本身并不一定是线程安全的,需要额外的同步机制来保护对象的访问。

unique_ptr不是线程安全的,不应该在多个线程之间共享。如果在需要多线程之间传递线程,可以使用std::move显式地转移线程。

weak_ptr本身也是线程安全的,但需要注意,在将weak_ptr转换为shared_ptr时,可能会出现竞争条件。

自定义器

智能闪电允许使用自定义删除器,用于在对象被推理时执行特定的操作。自定义器可以是一个函数、函数对象或lambda表达式。#include lt;iostreamgt;#include lt;memorygt;void customDeleter(int* ptr) { std::cout lt;lt; quot;自定义删除器名为\nquot;;delete ptr;}int main() { std::unique_ptrlt;int, void(*)(int*)gt; ptr(new int(10), customDeleter); //或者使用 lambda 表达式 std::shared_ptrlt;intgt;sharedPtr(new int(20),[](int* ptr) { std::cout lt;lt; quot;Lambda 删除器调用\nquot;;删除 ptr; }); return 0;}登录后复制

自定义删除器的主要用途:释放非内存资源:例如文件句柄、网络连接等。执行特定的清理操作:例如关闭数据库、释放连接锁等。与 CStyleAPI 集成:当需要使用 Cstyle 的释放函数时。

智能指针的性能考量

虽然智能指针提供了一些便利,但也带来了一些性能开销:引用计数:shared_ptr需要维护引用计数,增加了额外的开销。虚函数表:使用删除器,如果虚函数表的开销可能会增加。内存分配: Shared_ptr的控制和对象可能需要分别分配内存。

在性能敏感的场景下,需要仔细评估智能指针的性能影响,并选择合适的智能指针类型。在不需要共享共享的情况下,优先使用unique_ptr。

总结

C智能指针是管理块动态内存的强大工具,可以有效避免内存卸载和卸载理解指针。不同类型的智能指针的特点和适用场景,可以编写更安全、更可靠的C代码。记住,选择合适的智能指针是关键,并且需要严格处理与原始指针的交互,属于潜在的问题。

以上就是C怎么使用智能指针 C智能指针的类型与使用场景的详细内容,更多请关注乐哥相关常识网其他文章!

C++怎么使用智能指
Raydium(Ray)价格预测:Upbit列出Sparks Rally,但可以持续吗?
相关内容
发表评论

游客 回复需填写必要信息