我在考虑写这样的方法:
QString getData() {
QNetworkReply *reply = getReply();
reply->deleteLater();
return QString::fromUtf8(reply->readAll()).trimmed();
}
安全吗? 如果我被迫这样写:
QString getData() {
QNetworkReply *reply = getReply();
QString result = QString::fromUtf8(reply->readAll()).trimmed();
reply->deleteLater();
return result;
}
我正在两次封送QString(我是吗?,一旦它被放入结果,第二次按值返回),我想避免。
答案 0 :(得分:4)
来自deleteLater文档:
安排此对象删除。
当控件返回到事件循环时,将删除该对象。如果在调用此函数时事件循环未运行(例如,在QCoreApplication :: exec()之前在对象上调用deleteLater()),则在启动事件循环后将删除该对象。
所以你在那里做的是安全的。显然,分发可能持久化的对象(或其成员)的引用或指针是错误的。但如果你要复印件,那就没关系。
但你正在做什么可能会或可能不会做你想做的事。 readAll
不会阻止,它会返回当前可用的数据 。这意味着对readAll
的单次调用可能只会读取部分响应 - 除非您已确保所有数据都通过其他方式到达。
其他注意事项,来自文档:
注意,进入和离开新的事件循环(例如,通过打开模态对话框)将不执行延迟删除;对于要删除的对象,控件必须返回到调用deleteLater()的事件循环。
所以做这种事情时唯一要担心的是调用以某种方式重新进入“当前”事件循环的函数。但如果通过QCoreApplication::processEvents
:
如果您正在运行一个连续调用此函数的本地循环,而没有事件循环,则不会处理DeferredDelete事件。
所以这也涵盖了。延迟删除逻辑非常复杂,但在正常情况下是安全的。如果你正在深入挖掘Qt内部(或调用可能在那里做一些可疑事情的代码),那就要防守。但是对于正常的代码流,deleteLater
是安全的,只要你没有可能持久的悬挂引用(或指针)。
答案 1 :(得分:0)
deleteLater
做什么?从它的名字,我希望它在稍后的某个时间点(交易结束?会话结束?)注册对象以便删除。如果是这样,只要稍后的时间点没有发生,您就可以安全地使用它。唯一的问题是知道何时发生这一点,但是对于诸如交易结束或会话结束之类的事情,您可能是安全的 - 如果您在事务或会话中调用了您的函数,则事务或会话将在您返回之前不会结束。
答案 2 :(得分:-1)
这是安全的,但你最好不要使用deleteLater
,因为
当控件返回到事件循环时,将删除该对象。如果 调用此函数时事件循环未运行(例如 在QCoreApplication :: exec()之前在对象上调用deleteLater(), 一旦事件循环开始,该对象将被删除。
意味着可以删除对象mmm ... never。这假装像GC一样工作,但更糟糕的是:
class A: public QObject
{
char x[10000000];
};
void process()
{
A* a = new A();
//delete a;
a->deleteLater();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
for (int k = 0; k < 1000000; ++k) {
process();
}
return a.exec();
}
至少使用RAII不是C ++惯用语。
从另一个尺寸来看,复制QString
是一项廉价的操作,因为QSring
使用了写时复制的ideome。