Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从物体发出信号可以吗';Qt中的s析构函数?_C++_Qt - Fatal编程技术网

C++ 从物体发出信号可以吗';Qt中的s析构函数?

C++ 从物体发出信号可以吗';Qt中的s析构函数?,c++,qt,C++,Qt,当QObject派生对象被析构函数时,是否可以从其析构函数发出信号?我试过了,似乎很管用,但我不确定是否应该这样做 例如,此代码 class MyClass : public QObject { signals: void mySignal(const QString &str); public: QString myString; ~MyClass() { emit mySignal(myString); } } 将常量引用传递到一个对象,该对象在执行连接的插

当QObject派生对象被析构函数时,是否可以从其析构函数发出信号?我试过了,似乎很管用,但我不确定是否应该这样做

例如,此代码

class MyClass : public QObject {
signals:
    void mySignal(const QString &str);
public:
    QString myString;
    ~MyClass() { emit mySignal(myString); }
}

将常量引用传递到一个对象,该对象在执行连接的插槽时可能超出范围。

发射通常是正常的(QObject也会使用“已销毁”信号进行此操作),包括您的情况。当连接是直接连接时,该字符串仍处于活动状态。当它是QueuedConnection时,首先将字符串复制到事件循环。

如果您询问它是否正常:是,它本身不会导致任何问题

如果你想问在Qt中这样做是否安全?绝对不安全。如果您从析构函数发出,您必须非常注意您所做的事情,并且对Qt事件系统有很好的理解

请记住,当一个
QObject
子体析构函数时,它会断开所有信号的连接,这样被析构函数的对象就不会在其插槽上获得更多调用了?这里有一个陷阱:销毁令。
QObject
析构函数会断开连接,并且它是最后一个进行析构函数,这意味着,在销毁链中,事件仍可能到达“半死不活”对象,从而在访问虚拟函数和已销毁子体的成员时导致访问冲突。如果您使用事件系统,并且满足以下任何条件,则存在这种可能性:

  • 在多线程环境中,如果对象未在其自己的线程上被破坏
  • 在多线程环境中,如果对象的销毁链触发在任何运行路径上运行
    processEvents()
  • 在多线程环境中,如果另一个线程上的任何对象直接连接到此对象,并且它在直接连接中无法对其已破坏的信号作出反应
  • 在单线程环境中,当析构函数发送信号时 可能返回到直接连接链中的对象
我将这种效果称为“死亡中的生命”,在析构函数中发出信号或运行任何形式的
processEvents()
(通常是意外地)都会增加产生这种错误的机会


当然,如果您能以某种方式保证在销毁过程中不会有任何当前或未来的代码触发任何插槽,那么从析构函数发出消息是完全安全的,但很难给出这样的保证,我建议您尽可能避免这种情况。

但我假设sender()方法可能会给出无效指针?不管怎样,我想我在写插槽的时候应该小心并记住这一点。是的,当然。如果您有排队连接,则如果信号是在dtor中发出的,则不得使用sender()。信号接收器必须意识到这一点。