使用指向 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。
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。