我应该如何在Qt中存储指针

How should I store pointers in Qt?

本文关键字:存储 指针 Qt 我应该      更新时间:2023-10-16

我的宠物项目已经到了我应该开始跟踪指针寿命的地步,我正在尝试为它开发一些系统。遗憾的是,由于Qt API本身在任何情况下都使用裸指针,因此在任何地方使用智能指针的流行建议都不适用。所以,我想到的是:

  1. 对于Qt、所有的一切

    • 在本地使用裸指针
    • 在函数之间也裸体传递它们
    • 将它们存储为子类CCD_ 1,使CCD_
  2. 对于我干净拥有的所有东西,请按照建议使用智能指针。我将在这里使用std::版本。

  3. 困扰我的情况。对于切换所有权的对象(如从布局中添加/删除的小部件)

    • 裸使用、存储、传递指针
    • 在适当的时候手动delete

建议、意见、建议?我自己也不太喜欢这个计划。

首先,尽可能按值保存。对newmake_uniquemake_shared的每次使用都持怀疑态度——您必须证明每次创建动态对象的合理性。如果子对象的生存期与父对象相同,那么按值保存是一件很容易的事。例如:

class MyWidget : public QWidget {
Q_OBJECT
QGridLayout m_topLayout{this};
QLabel m_sign{"Hello World"};
public:
MyWidget(QWidget * parent = nullptr) : QWidget{parent} {
m_topLayout.addWidget(&m_sign, 0, 0);
}
};

你在四处传递指针,但对象所有权是明确的,并且没有所有权的改变仅仅因为QObject有一个父级并不意味着父级"拥有"它。如果子级在父级之前被销毁,则所有权将终止。通过使用C++语义(即成员构造和销毁的定义良好的顺序),您可以完全控制子生存期,并且QObject父级无法干预。

如果您有一个所有者的不可移动对象,请使用QPointer0并将其四处移动。这是围绕您自己的代码传递动态创建的QObject的方法。如果有QObject父级管理它们的所有权,则可以将它们从指针中删除。

如果您有共享所有权的对象,它们的寿命应该尽快结束(与应用程序终止或某个长期存在的对象被销毁相比),请使用std::shared_ptr。确保指针的寿命比用户长。例如:

class MyData : public QAbstractItemModel { /* ... */ };
class UserWindow : public QWidget {
Q_OBJECT
std::shared_ptr<MyData> m_data; // guaranteed to outlive the view
QTreeView m_view;
public:
void setData(std::shared_ptr<MyData> && data) {
m_data = std::move(data);
m_view.setModel(m_data.data());
}
};

这个例子可能是人为的,因为在Qt中,大多数对象用户都会观察对象的destroyed()信号,并对对象的破坏做出反应。但是,如果例如m_view是无法跟踪数据对象生命周期的第三方C API对象句柄,则这是有意义的。

如果对象的所有权在线程之间共享,那么std::shared_ptr的使用是必不可少的:destroyed()信号只能在单个线程中使用。当您在另一个线程中得知对象删除时,已经太晚了:对象已经被销毁。

第三,当您从工厂方法返回动态创建的对象的实例时,您应该通过裸指针返回它们:很明显,工厂创建了一个对象供其他人管理。如果您需要异常安全,您可以返回std::unique_ptr

对于初学者来说,在罗马,是罗马人
QT是在90年代早期开发的,在当时取得了巨大成功
不幸的是,随着时间的推移,QT并没有真正采用新的功能,因此API本身有非常古老的C++风格(我可以说是Java风格吗?)

你不能强迫QT突然变成C++14,因为它不是。当涉及到QT时,请使用流行的QT约定。如果这是平台设计的目标,请使用原始指针。如果不能,请使用值类型。

但我不认为QT能在C++14中发挥那么大的作用。按照平台给出的QT习惯用法进行粘贴。