使用指向 QObject 的原始指针作为信号参数是否安全?

Is it safe to use a raw pointer to a QObject as a signal argument?

qt doc 说:

it is of little value to declare functions to take a QPointer as a parameter; just use normal pointers. Use a QPointer when you are storing a pointer over time.

但是使用指向 QObject 的普通指针作为信号参数是否也安全?

如果信号连接到带有 Qt::QueuedConnection 的槽,并且参数对象在槽被调用之前被销毁,会发生什么情况?

class MyObject : public QObject
{
  Q_OBJECT
public:
  explicit MyObject(QObject *parent = nullptr) : QObject(parent) {}

signals:
  void mySignal_A(QObject *parameter);
  void mySignal_B(QPointer<QObject> parameter);
};

它的行为与使用无效指针调用普通成员完全相同。如果你在插槽中使用这个 QObject 那么你会得到 UB - 但是你可以使用 QWeakPointer 而不是原始 QObject 指针来控制你的 QObject 是否在另一个上下文中被破坏

在排队的 signal/slot 连接中将指针作为参数传递是不安全的,如果您已经怀疑指向的对象可能同时被删除。我认为文档指的是同步函数调用(也适用于直接连接)。

您可以使用 QPointer 或 QSharedPointer/QWeakPointer(或 C++11 的 std::shared_ptr/std::weak_ptr)。共享指针只有在 QObject 没有父对象的情况下才能安全使用。

更好的是,尽可能避免传递 QObjects。