什么时候使用QTimer调用多个函数调用的析构函数?
我有一个类在其析构函数中完成一个动作。 它在调用另一个函数等的单独的类的函数中调用。什么时候使用QTimer调用多个函数调用的析构函数?
void method3()
{
//action gets done
}
void method2()
{
//action gets done
method3();
}
void method1()
{
obj o;
//action gets done
QTimer::singleShot(1000, this, SLOT(method2()));
}
不使用QTimer::singleShot
,只是调用method2()
method3()
完成后调用析构函数。
什么时候使用QTimer::singleShot
调用method2()
时obj的析构函数被调用? 是否有使用QTimer::singleShot
并且在method3()
的末尾有正常调用的析构函数?
o
具有automatic storage class,这意味着它在封闭块结束时释放:
void method1()
{
obj o;
//action gets done
QTimer::singleShot(1000, this, SLOT(method2()));
} // o ceases to exist here
method2
计划在未来某一时刻运行,method1
返回之后值得注意的是,这样的自动变量的声明method1
的信息现在不能提供。
如果需要o
坚持你可以
声明
o
作为类的成员,如method1
似乎是某个类的成员函数与
new
分配它,或者更好,使用智能指针(可能是std::unique_ptr
将是最适合的),并在不再使用时手动释放它。
由于obj
类型的o
对象具有自动storage duration的method1
范围内时,它会被当提到范围结束破坏,即method1
饰面。
在第一种情况下,当您拨打method2
而没有QTimer::singleShot
时,您只是执行了一次正常的函数调用,它将返回到method1
。因此,当method2
返回时,method1
将完成。
在第二种情况下,您通过呼叫QTimer::singleShot
创建了一个事件,该事件将在事件创建后立即返回,因此method1
将在method2
的呼叫发生之前完成。
太延长o
对象的生命周期,你必须与动态存储时间创建它,那么当method3
完成摧毁它。这可以通过new
和delete
运营商完成,但我建议使用QSharedPointer
或其他智能指针。
这是我解决您的问题:
#include <QSharedPointer>
#include <QTimer>
#include <QtDebug>
#include <QObject>
class obj {
public:
obj() { qDebug() << "Instance of 'obj' is created."; }
~obj() { qDebug() << "Instance of 'obj' is destroyed."; }
};
class Foo : public QObject {
Q_OBJECT
public slots:
void method3() {
qDebug() << "Foo::method3 called.";
m_obj.reset(); // destroys the previously created 'obj' instance
}
void method2() {
qDebug() << "Foo::method2 called.";
method3();
}
void method1() {
m_obj.reset(new obj); // creates a new 'obj' instance
qDebug() << "Foo::method1 called.";
QTimer::singleShot(1000, this, SLOT(method2()));
}
private:
QSharedPointer<obj> m_obj;
};
在这种情况下,您可以创建o
只有当定时器的实际激活。当定时器的实际激活(执行该拉姆达)不是当method1()
被称为
void method1()
{
QTimer::singleShot(1000, this, [this]
{
obj o;
// Do your stuff here.
method2();
});
}
这里,不仅创造o
:您可以使用一个lambda函数。
如果这不适合您的用例,并且在调用method1()
时确实需要创建对象,而不是在定时器激活时创建该对象,则可以使用共享指针来防止在定时器触发之前销毁对象:
#include <memory>
// ...
void method1()
{
auto o_ptr = std::make_shared<obj>(/* ctor arguments here */);
// Do your stuff here.
QTimer::singleShot(1000, this, [o_ptr, this]{ method2(); });
}
由于我们拍摄的拉姆达o_ptr
,对象是不会被破坏。它只会在拉姆达完成后被销毁。 shared_ptr
保证如果任何人仍然持有对shared_ptr
的引用,则其保存的对象不会被销毁。在这种情况下,lambda持有一个引用来保持对象的活着。一旦lambda完成执行,引用被释放并且对象被销毁。
不完全正确:在两种情况下,method1完成时调用析构函数。当你使用异步机制如QTimer(免责声明我对QT一无所知,但是从基本C++原则的知识来讲)时,基于本地堆栈的对象的生命周期结束时,它们的创建范围就结束了。如果你想延长对象的生命周期,它首先需要基于堆(忽略全局变量)。您最好的选择是使用共享指针并将其传递给method2,然后将其作为原始指针或对method3的引用,因为它是同步调用的。 –