1

假设我有一个像下面这样的类:

#include <Object>
#include <QProcess>

class MyClass: public QObject {
private:
    QPointer<QProcess> m_process{ nullptr };
public:
    MyClass(QObject *parent = nullptr)
        : QObject{ parent }
        , m_process{new QProcess{} }
    {
        QObject::connect(m_process, &QProcess::errorOccurred,
            this, [](QProcess::ProcessError error) {
            qDebug() << "error: " << error;
            });
    }
    ~MyClass()
    {
        if (m_process)  delete m_process; //--> is it necessary?
    }
};

我是否需要m_process手动删除,如析构函数中所示?

不幸的是,我不能使用std::unique_ptror std::shared_ptr

QObject::connect(m_process, &QProcess::errorOccurred,
            this, [](QProcess::ProcessError error) {
            qDebug() << "error: " << error;
            });

我还没有看到QObject::connect.

另一方面,在QPointer::~QPointer()我读过:

销毁受保护的指针。就像普通指针一样,销毁受保护的指针不会破坏指向的对象。

这意味着QPointer::~QPointer()将 delete asMyClass的对象超出范围,因此我要删除m_process两次?

还是我误会了?

4

2 回答 2

3

的目的QPointer是提供指向QObject子类的受保护或弱指针。当它超出范围时它不会删除对象,它只知道它指向的对象是活动的还是已经删除。

所以你当前的代码在这个意义上是正确的。几点评论:

  • 在变量声明中为指针设置默认值是没有用nullptr的,因为您在构造函数初始化程序列表中对其进行了初始化。
  • 您不需要在删除之前检查指针是否为空,因为delete nullptr;是有效的代码,它什么都不做。
  • 如果你QProcess的生命周期与包含对象的生命周期相同,那么你应该把它作为一个成员变量,根本不要使用new,除非你有一些特定的原因。
  • 如果您确实想使用new它来分配它,请考虑是否QProcess可以有一个 parent QObject,这将删除它。
  • 或者,您应该将指针包装在QScopedPointeror中std::unique_ptr,因为它们拥有它们指向的对象,并且会在超出范围时将其删除。
于 2019-05-04T17:32:03.930 回答
1

QPointer不是智能指针。它不管理它指向的对象。它只是跟踪它是否被删除。您需要自己删除它:

~MyClass()
{
    delete m_process.data();
}

当您删除指向的对象时,data()将为空。

你不需要在删除它之前检查它是否为空,因为删除一个空指针是可以的(它只是不做任何事情。)

我不认为你需要在QPointer这里。如前所述,此类仅用于跟踪对象是否已在其他地方删除。您可能根本不应该在这里使用指针。做就是了:

#include <QProcess>

class MyClass: public QObject {
private:
    QProcess m_process;
// ...

并将您的连接代码更改为:

connect(&m_process, &QProcess::errorOccurred, this, [](QProcess::ProcessError error)
{
    qDebug() << "error: " << error;
});
于 2019-05-04T17:29:14.060 回答