C++ 如果指针指向新对象,信号/插槽连接会发生什么情况
我有一个上传程序,代码如下:C++ 如果指针指向新对象,信号/插槽连接会发生什么情况,c++,qt,signals-slots,C++,Qt,Signals Slots,我有一个上传程序,代码如下: if(!_canceled) { _reply = _accessManager.put(request, item); if(_reply) { _currentItem = item; bool status = connect(_reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(reportUploadProgress(qint64, qin
if(!_canceled) {
_reply = _accessManager.put(request, item);
if(_reply) {
_currentItem = item;
bool status = connect(_reply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(reportUploadProgress(qint64, qint64)));
pantheios::log(pantheios::debug, "StorageProvider(): connection uploadProgress(qint64, qint64), status", pantheios::boolean(status));
status = connect(_reply, SIGNAL(finished()), this, SLOT(handleFinishedRequest()));
pantheios::log(pantheios::debug, "StorageProvider(): connection finished(), status", pantheios::boolean(status));
} else {
emit noReply();
pantheios::log(pantheios::error, "StorageProvider(): no reply", item.toUtf8());
}
然后在完成的插槽中,我执行以下操作:
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
if(reply->error() > QNetworkReply::NoError) {
pantheios::log(pantheios::error, "StorageProvider(handleFinishedRequest) ", reply->errorString().toUtf8());
if((reply->error() == QNetworkReply::TemporaryNetworkFailureError) || (reply->error() == QNetworkReply::ContentReSendError)) {
// retry the last request
_reply = accessManager.put(reply->request(), _currentItem);
}
} else {
...
}
QNetworkReply*reply=qobject_cast(sender());
如果(reply->error()>QNetworkReply::NoError){
pantheios::log(pantheios::error,“StorageProvider(handleFinishedRequest)”,reply->errorString().toUtf8();
如果((回复->错误()==QNetworkReply::TemporaryNetworkFailureError)| |(回复->错误()==QNetworkReply::ContentReSendError)){
//重试最后一个请求
_reply=accessManager.put(reply->request(),_currentItem);
}
}否则{
...
}
此StorageProvider将能够处理不同的请求,而回复将具有不同的连接,具体取决于创建它的功能。回复是成员变量的原因是,我可以在执行下一个请求之前删除它
所以,我的问题是,如果我重新发布回复,我是否需要再次连接?插槽/信号是否连接到指针或对象?还有,有没有更好的方法删除旧的回复
编辑:将完成请求的处理者的代码更改为此
if(_currentReply->error() > QNetworkReply::NoError) {
pantheios::log(pantheios::error, "StorageProvider(handleFinishedRequest) ", _currentReply->errorString().toUtf8());
if(((_currentReply->error() == QNetworkReply::TemporaryNetworkFailureError) || (_currentReply->error() == QNetworkReply::ContentReSendError)) && (_currentRetries < 4)) {
QNetworkRequest lastRequest = _currentReply->request();
_currentReply->deleteLater();
_currentReply = _accessManager.put(lastRequest, _currentItem);
if(_currentReply) {
bool status = connect(_currentReply, SIGNAL(uploadProgress(qint64, qint64)), this, SLOT(reportUploadProgress(qint64, qint64)));
pantheios::log(pantheios::debug, "StorageProvider(retry): connection uploadProgress(qint64, qint64), status", pantheios::boolean(status));
status = connect(_currentReply, SIGNAL(finished()), this, SLOT(handleFinishedRequest()));
pantheios::log(pantheios::debug, "StorageProvider(retry): connection finished(), status", pantheios::boolean(status));
} else {
emit noReply();
pantheios::log(pantheios::error, "StorageProvider(retry): AccessManager no reply");
}
}
}
if(_currentReply->error()>QNetworkReply::NoError){
pantheios::log(pantheios::error,“StorageProvider(handleFinishedRequest)”,\u currentReply->errorString().toUtf8());
如果(((U currentReply->error()==QNetworkReply::TemporaryNetworkFailureError);(U currentReply->error()==QNetworkReply::ContentReSendError))&&((U currentRetries<4)){
QNetworkRequestLastRequest=\u currentReply->request();
_currentReply->deleteLater();
_currentReply=\u accessManager.put(lastRequest,\u currentItem);
如果(_currentReply){
bool status=connect(_currentReply,SIGNAL(上传进度(qint64,qint64)),此插槽(reportUploadProgress(qint64,qint64));
pantheios::log(pantheios::debug),“StorageProvider(重试):连接上传进度(qint64,qint64),状态”,pantheios::boolean(状态));
状态=连接(_currentReply,SIGNAL(finished()),this,SLOT(handleFinishedRequest());
pantheios::log(pantheios::debug),“存储提供程序(重试):连接完成(),状态”,pantheios::boolean(状态));
}否则{
发射noReply();
pantheios::log(pantheios::error,“StorageProvider(重试):AccessManager无应答”);
}
}
}
信号连接到对象,而不是指针变量,因此每次都必须建立新的连接
要删除回复,只需在finished()
槽的开头调用deleteLater()
:
QNetworkReply *reply = qobject_cast<QNetworkReply*>(sender());
reply->deleteLater();
您将创建如下请求:
if(!_canceled) {
PutRequest *putRequest = new PutRequest(_accessManager, request, item);
// and you connect putRequest object signals to whatever you connected _reply to
在尝试执行重试逻辑时,我还应该记住什么?当谈到qt时,有没有一个好的方法来练习它?跟踪什么样的上传、即时消息、重新键入等的方法。atm我一次只有一个请求,然后保存上传项目,以便在重新键入时使用。如果我使用回复的请求,然后删除回复,会发生什么情况?代码的另一个问题是,您通常应该避免使用
sender()
(Qt文档解释了原因)。您可以创建一个QObject
派生类来处理每次下载,其中包含\u reply
成员、初始请求及其自己的finished()
插槽,您可以使用相同的“下载”重试对象。QNetworkRequest
未链接到QNetworkReply
对象,因此您可以安全地复制它并在以后删除回复。因此,如果类具有“currentItem”,它将不起作用这是当前上传的对象吗?该类将只处理一个调用,并且在该调用完成之前不会启动新的调用。这是一种方法吗?
if(!_canceled) {
PutRequest *putRequest = new PutRequest(_accessManager, request, item);
// and you connect putRequest object signals to whatever you connected _reply to