[英]Smart pointers and avoid manual memory management when using QNetworkAccessManager
我有以下 class 调用一些 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;
}
};
我以这种方式使用 class:
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
现在这显然涉及一些手动 memory 管理,我必须小心不要忘记删除原始指针。 我想知道是否可以使用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
吗?
好的,经过一番思考,我想出了一个解决方案。 我想解决的主要问题是避免手动删除我的QNetworkReply*
object,而是希望在删除NetworkRequest
实例时自动销毁它。 In order to achieve this, I used a std::unique_ptr
as a private member of my NetworkRequest
class so when the class is destroyed, the unique_ptr
automatically cleans the object in memory. Furthermore, by default std::unique_ptr
deletes the object it hold upon reassignment, so whenever I call the send
function in my, I can assign a new object to the smart pointer and the previous object in memory will get deleted automatically. 需要注意的一件事是,Qt 文档建议使用QObject::deleteLater()
删除QNetworkReply*
(我不完全清楚为什么会这样),为了做到这一点,可以使用自定义删除器. 所以在我的代码中,我声明了一个私有成员,如下所示:
private:
struct deleteLaterDeletor
{
void operator()(QObject *object) const
{
if(object) {
object->deleteLater();
}
}
};
using ReplyPointer = std::unique_ptr<QNetworkReply, deleteLaterDeletor>;
ReplyPointer m_reply;
然后在我send
function 中:
m_reply = ReplyPointer(mNetManager->get(netRequest));
显然,在信号和槽的签名中,我必须传递原始指针( m_reply.get()
)。
( QSharedPointer
也可以用来代替std::unique_ptr
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.