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

Qt 智能指针QScopedPoint用法

1. 智能指针是什么

智能指针是C++11引入的一种指针封装类型,用于自动管理动态分配的内存。智能指针的目的是解决传统裸指针带来的内存泄漏、悬挂指针等问题,并使代码更安全、更易读。

2. 智能指针有什么用

1.自动管理内存,避免内存泄漏和悬挂指针问题;
2.简化代码,减少异常处理和资源管理的复杂性;
3.提高代码可读性和可维护性;
4.帮助实现RAII(资源获取即初始化)原则,更好地管理资源。

3. 智能指针和普通指针区别

智能指针和普通指针的主要区别在于内存管理方式。普通指针(裸指针)直接使用内存地址,需要手动申请和释放内存,容易导致内存泄漏和悬挂指针等问题。而智能指针封装了内存地址,通过自动管理内存的方式避免了这些问题。
智能指针内部维护了一个引用计数器,当一个智能指针被创建或拷贝时,计数器加1;当一个智能指针被销毁或重置时,计数器减1。当计数器减至0时,智能指针会自动释放其所指向的内存。这种方式称为“所有权”(ownership)模型,智能指针具有其内存的所有权,避免了普通指针中的多个指针指向同一内存地址的情况。
另外,智能指针还提供了一些有用的成员函数,如reset()release()等,可以更方便地进行内存管理。同时,智能指针的类型也不同,如std::unique_ptr表示独占所有权的智能指针,std::shared_ptr表示共享所有权的智能指针,std::weak_ptr表示观察智能指针等。

4. QScopedPoint介绍

QScopedPointer类用于存储一个指向动态分配的对象的指针,并在对象销毁时自动删除它。
手动管理堆分配的对象是困难且容易出错的。常见的后果是代码内存泄漏,难以维护。QScopedPointer是一个小工具类,通过将基于堆栈的内存所有权分配给堆分配,一般称资源获取即初始化(RAII),从而大大简化了这一点。
QScopedPointer保证当当前作用域消失时,所指向的对象将被删除。
当使用QScopedPointer时,可以确保在函数退出时,所分配的对象会被自动删除,从而避免了内存泄漏。这使得代码更简洁、更安全,减少了内存泄漏和代码错误的风险。
比如:一般我们自行new在堆中创建对象时,需手动管理内存,如下:

  void myFunction(bool useSubClass){MyClass *p = useSubClass ? new MyClass() : new MySubClass;QIODevice *device = handsOverOwnership();if (m_value > 3) {delete p;delete device;return;}try {process(device);}catch (...) {delete p;delete device;throw;}delete p;delete device;}

如果改用智能指针,代码清晰易懂

  void myFunction(bool useSubClass){// assuming that MyClass has a virtual destructorQScopedPointer<MyClass> p(useSubClass ? new MyClass() : new MySubClass);QScopedPointer<QIODevice> device(handsOverOwnership());if (m_value > 3)return;process(device);}

如果被const修饰,普通指针与智能指针的对比:

      const QWidget *const p = new QWidget();// 等同于const QScopedPointer<const QWidget> p(new QWidget());QWidget *const p = new QWidget();// 等同于const QScopedPointer<QWidget> p(new QWidget());const QWidget *p = new QWidget();// 等同于QScopedPointer<const QWidget> p(new QWidget());

5. QScopedPoint用法

首先包含头文件

#include <QScopedPointer>
    QScopedPointer<int> pInt(new int(99));qDebug().noquote() << "*pInt :" << *pInt << *pInt.data(); // 99 99

使用很简单。

6. take()和data()方法区别

QScopedPointer 有两个重要的方法:take()data()

  1. take() 方法
    • take() 是一个成员函数,它允许你获取 QScopedPointer 所指向的对象,并将 QScopedPointer 设置为 null。这意味着一旦调用了 take()QScopedPointer 将不再拥有该对象,并且不再负责其生命周期。
    • 这个方法通常用于在多线程环境中安全地传递对象,或者在知道对象生命周期的情况下安全地获取对象。
  2. data() 方法
    • data() 返回一个指向所持有对象的指针。这个方法主要用于访问或修改所指向的对象。
    • 注意,尽管 data() 返回一个指针,但这个指针的生命周期依赖于 QScopedPointer 的生命周期。如果 QScopedPointer 被销毁,那么这个指针将变得无效。
      使用注意事项
  • 使用 take() 时要特别小心,确保在 take() 之后,不会意外地使用 QScopedPointer,因为这样可能会导致未定义的行为。
  • 使用 data() 时,要确保在 QScopedPointer 的生命周期内使用返回的指针,否则可能会导致悬挂指针或其他问题。

如下示例:

#include <QScopedPointer>  class MyClass {  
public:  MyClass() {  // 初始化操作  }  ~MyClass() {  // 清理操作  }  void show() {  // 显示对象内容  }  
};  int main() {  QScopedPointer<MyClass> ptr(new MyClass); // 创建一个 MyClass 对象,QScopedPointer 管理其生命周期  // 使用 data() 方法访问对象  MyClass* rawPtr = ptr.data(); // 返回原始指针,QScopedPointer 仍然拥有这个对象  rawPtr->show(); // 显示对象内容  // 使用 take() 方法转移对象所有权  MyClass* takenPtr = ptr.take(); // take() 返回原始指针,QScopedPointer 不再拥有这个对象  takenPtr->show(); // 显示对象内容,然后释放 takenPtr,不调用 MyClass 的析构函数  return 0;  
}

http://www.mrgr.cn/news/58123.html

相关文章:

  • 甲骨文API自动开机器程序
  • MySql中表的约束
  • Linux运行时动态库搜索路径优先级
  • table表格中内嵌表单案例
  • 论文《Text2SQL is Not Enough: Unifying AI and Databases with TAG》
  • 一文带你搞定Java中的动态代理和静态代理
  • 【已解决】【hadoop】【hive】启动不成功 报错 无法与MySQL服务器建立连接 Hive连接到MetaStore失败 无法进入交互式执行环境
  • Golang | Leetcode Golang题解之第507题完美数
  • 将二维图像映射到三维场景使用NeRF在AMD GPU上
  • <自用> python 更新库命令
  • Codeforces Round 981 div3 个人题解(A~G)
  • AI学习指南深度学习篇-自注意力机制(Self-Attention Mechanism)
  • 基于 Python 的自然语言处理系列(43):Question Answering
  • 【C++差分数组】P10903 商品库存管理
  • 003:无人机概述
  • 【MySQL】数据库约束和多表查询
  • Hugging Face HUGS 加快了基于开放模型的AI应用的开发
  • 前端方案:播放的视频加水印或者文字最佳实践
  • 【蓝桥杯选拔赛真题78】python电话号码 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析
  • 吊打ControlNet?全能型图像生成模型OmniGen问世,简单提示实现图像生成与精细编辑
  • Shopee虾皮登录不了的常见原因及解决方式
  • 百科知识|选购指南
  • 驱动-----向内核新加文件
  • Apache配置案例二:基于域名的虚拟主机搭建
  • linux下gpio模拟spi时序
  • Ajax笔记