[英]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.