【发布时间】:2019-10-02 11:55:14
【问题描述】:
我有以下类调用一些 HTTP API 请求到服务器:
class NetworkRequest : public QObject {
public:
NetworkRequest(QNetworkAccessManager* netManager):
m_netManager(netManager){}
void send(QUrl const &url){
QNetworkRequest request(url);
auto reply = m_netManager->get(request);
connect(reply, &QNetworkReply::finished, [this, reply](){
// do some stuff with reply (like if url is redirected)
if(isRedirected(reply)){
// we have to delete the reply and send a new one
QUrl newUrl;
// somehow get the new url;
reply->deleteLater();
send(newUrl);
}
else{
reply->setParent(this); // so that it will be deleted when an instance of this class is deleted
emit completed(reply);
}
});
}
signals:
void completed(QNetworkReply* reply);
private:
QNetworkAccessManager* m_netManager;
bool isRedirected(QNetworkReply * reply){
bool yes = false;
/* process the process reply and determine yes is true or false
....
**/
return yes;
}
};
我是这样使用类的:
auto req = new NetworkRequest(nm);
req->send("http://someurl.com");
connect(req, &NetworkRequest::completed, randomClass, &RandomClass::slot);
// in RandomClass::slot I call NetworkRequest::deleteLater() when I finished with the network data
现在这显然涉及一些手动内存管理,我必须小心不要忘记删除原始指针。我想知道是否可以使用QSharedPointer(甚至std::shared_ptr)编写上面的代码并替换:
auto reply = m_netManager->get(request);
与:
auto smartReply = QSharedPointer<QNetworkReply>(m_netManager->get(request));
然后用smartReply.get() 替换所有reply 实例,然后忘记手动删除回复对象。但是,我不清楚共享指针是否会自动删除对象,因为在我调用send() 和信号QNetworkReply::finished 之间,智能指针会知道原始指针仍在使用中吗?另外,当我删除NetworkRequest 的实例时,共享指针会自动删除它拥有的QNetworkReply 吗?
【问题讨论】:
-
Qt 文档说,您应该删除回复,但不是直接在插槽中,而是使用
deleteLater()。看起来您在代码中正确执行了此操作。 -
@vahancho 那么可以使用带有自定义删除器的
QSharedPointer吗? (doc.qt.io/qt-5/qsharedpointer.html#QSharedPointer-2) -
它可能会被使用,但我没有看到使用共享指针的意义。谁分享指针?在这种情况下,作用域或唯一指针将更合适,IMO。
-
但是在
QNetworkReply::finished发出之前范围不会结束吗? -
范围是
send()函数。但无论如何,我不会使用智能指针来管理不是由我创建的指针的生命周期。
标签: c++ qt smart-pointers signals-slots qsharedpointer