Qt 在QObject派生类的构造函数中使用deleteLater

Qt 在QObject派生类的构造函数中使用deleteLater,qt,qml,qtquick2,dbus,networkmanager,Qt,Qml,Qtquick2,Dbus,Networkmanager,我发现了一些东西,它看起来像是一个习惯用法,用于导出到QML的C++对象中指针类型的属性。由于外部事件的发生,这些属性的指针对象可以随时停止存在。为此,我使用QObject::deleteLaterslot已更改信号(QML所需)可以连接到QObject::destroyed信号。我注意到,在发出此信号时,QPointer已清除。所以属性值在适当的时候在QML端是有效的 通过查看QPointer标题,我注意到它是基于QWeakPointer/QSharedPointer的,并且似乎使用了行为(即

我发现了一些东西,它看起来像是一个习惯用法,用于导出到QML的C++对象中指针类型的属性。由于外部事件的发生,这些属性的指针对象可以随时停止存在。为此,我使用
QObject::deleteLater
slot<代码>已更改信号(QML所需)可以连接到
QObject::destroyed
信号。我注意到,在发出此信号时,
QPointer
已清除。所以属性值在适当的时候在QML端是有效的

通过查看
QPointer
标题,我注意到它是基于
QWeakPointer
/
QSharedPointer
的,并且似乎使用了行为(即“
QPointer
在调用连接到
销毁的
信号的第一个插槽之前变得清晰”),虽然没有在文档中指定,但在某种程度上是硬设置的

在我的例子中,属性是指向
QDBusAbstractInterface
-派生类[]的指针,它对应于NetworkManager D-Bus服务接口。NetworkManager D-Bus服务可能会意外注销,并且上述所有类都变得不可用,并且每个类的
QDBusAbstractInterface::isValid()
都变得
false

QDBusAbstractInterface
派生类的生命周期内,在创建派生类之后,我可以通过
QDBusServiceWatcher
watcher来管理这种情况

但是在创建
QDBusAbstractInterface
派生类的过程中,我不能依赖于服务可用性。即使我通过
QDBusConnection::systemBus().interface()->isServiceRegistered(QStringLiteral(NM_DBUS_服务))
检查服务的可用性,它也可能在下一个操作员之前立即变得不可用(就C++而言)。因此,构建的类在其
QDBusAbstractInterface
基础构建之后可能无法使用(即
QDBusAbstractInterface::isValid()
is
false

我当前所做的是根据
isValid()
deleteLater()
[]调用到构造函数中。在我看来,一旦到达事件循环,在构建对象之后,这最终会导致对象的破坏

是否允许在
QObject
派生类的构造函数中调用
deleteLater()
插槽

是否允许在的构造函数中调用deleteLater()slot QObject派生类

这只是处理无效对象的一种不寻常且不明显的方式(类使用者可能不期望它),在使用类工厂模式创建类实例之前,我们始终可以检测该类实例是否无效:

class MyNetworkManager
{
public:
   // static create method
   static MyNetworkManager* create();

private:
   // private constructor
   MyNetworkManager();
};

/*static*/ MyNetworkManager* MyNetworkManager::create()
{
   // This method may contain all the necessary logic
   // to avoid producing an invalid class instance.
   if (nwkSystem.isReady())
       retrun new MyNetworkManager;

   return nullptr;
}

// usage would be
auto* p = MyNetworkManager::create();
if (!p)
{
    qDebug() << "the system is not ready for MyNetworkManager";
}
类MyNetworkManager
{
公众:
//静态创建方法
静态MyNetworkManager*创建();
私人:
//私有构造函数
MyNetworkManager();
};
/*static*/MyNetworkManager*MyNetworkManager::create()
{
//此方法可能包含所有必要的逻辑
//以避免生成无效的类实例。
if(nwkSystem.isReady())
重新运行新的MyNetworkManager;
返回空ptr;
}
//用法将是
auto*p=MyNetworkManager::create();
如果(!p)
{

qDebug()似乎你没有很好地理解这个问题。在你的回答中,在执行
nwkSystem.isReady()之间
新建MyNetworkManager
前一个可能会变成
false
。我特别指出了这一点。@Orient,答案当然很简单,但你可以确保使用与构造函数中相同的代码,而不是构造函数中的代码。我查看了你的代码,…如果类的实例在它的生命周期,然后信号可以发送给类的使用者,deleteLater()将是一些隐含的误导行为。我同意。似乎最好在构造之后立即检查
isValid()
,并将
delete
应用于原始指针……并且在检查之前不要通过
setProperty
分配新值。