Signals
-
Hi,
QObject::connect(reply.get(), &QNetworkReply::finished, this, std::bind(&Request::OnFinished, this, request, reply.get()));
'QNetworkReply': cannot instantiate abstract class
why is it give an error?
-
The connect call looks a bit scary to me. What exactly should it achieve? Why is
std::bind
needed?
"Cannot instantiate abstract class" means that the class to be instantiated has unimplemented methods. Typically virtual ones to be overridden.
SinceQNetWorkReply
is fully implemented and you usereply.get()
to obtain a pointer (from astd::unique_ptr
?) on both sides of the statement, you may want to look for such missing implementation(s) atRequest
or whateverstd::bind
produces. -
@Axel-Spoerl said in Signals:
The connect call looks a bit scary to me. What exactly should it achieve? Why is std::bind needed?
"Cannot instantiate abstract class" means that the class to be instantiated has unimplemented methods. Typically virtual ones to be overridden.
Since QNetWorkReplyis fully implemented and you use reply.get()to obtain a pointer (from a std::unique_ptr?) on both sides of the statement, you may want to look for such missing implementation(s) at Requestor whatever std::bindproduces.Out of curiosity, how can this be done via std::bind? Or show example for connect
-
Honestly, that's the first time I see this kind of connect statement. Haven't got any running example and I don't use it that way myself.
-
@continue98
We don't know what yourthis
is, nor what is inRequest
class. There may be your issue. Though I admit error message'QNetworkReply': cannot instantiate abstract class
does not look like that.For the record, Why use std::bind over lambdas in C++14?. Not a lot of point. You could retry your
connect()
statement to use a lambda and see whether you still receive that same error message, to test whether thestd::bind()
is relevant to the problem here. -
to the problem here.
lambdas are inconvenient in my cases, I need a callback (via a method)
hxx:
#pragma once #include <QtCore/qobject.h> #include <QtNetwork/qnetworkaccessmanager.h> #include <QtNetwork/qnetworkreply.h> class Request : public QObject { Q_OBJECT public: Request(QObject* parent = nullptr); void send(); void OnFinished(QNetworkRequest request, QNetworkReply* reply); public slots: void finished(); private: std::shared_ptr<QNetworkAccessManager> m_manager; };
cxx:
#include "request.hxx" Request::Request(QObject* parent) : QObject{ parent } { m_manager = std::make_shared<QNetworkAccessManager>(QNetworkAccessManager(this)); } void Request::send() { QNetworkRequest request; QSslConfiguration config = QSslConfiguration::defaultConfiguration(); config.setProtocol(QSsl::TlsV1_2); request.setSslConfiguration(config); request.setUrl(QUrl("https://www.fairssl.net")); request.setHeader(QNetworkRequest::ServerHeader, "application/json"); m_reply = std::make_shared<QNetworkReply>(m_manager.get()->get(request)); QObject::connect(m_reply.get(), &QNetworkReply::finished, this, std::bind(&Request::OnFinished, this, request, m_reply.get())); } void Request::OnFinished(QNetworkRequest request, QNetworkReply* reply) { }
-
@continue98 said in Signals:
lambdas are inconvenient in my cases, I need a callback (via a method)
I don't understand. Most people call a method if required from a lambda. I also suggested you try with lambda instead of
std::bind
to see if it affected the error message or not. Up to you. -
@continue98 said in Signals:
m_reply = std::make_shared<QNetworkReply>(m_manager.get()->get(request));
This is where your error comes from. QNetworkReply has no ctor which takes a pointer to another network reply. Simply don't use a shared pointer here and use deleteLater() later on.
Your std::bind stuff can be rewritten to
connect(m_reply.get(), &QNetworkReply::finished, this, this, request { OnFinished(request, m_reply.get()); });
Even capturing the request is not needed - see QNetworkReply::request(). And since m_reply is a member var it's getting even easier
connect(m_reply.get(), &QNetworkReply::finished, this, &Request::OnFinished);
void Request::OnFinished() { use m_reply here}On more note on which std::shared_ptr & QObject's are bad:
m_manager = std::make_shared<QNetworkAccessManager>(QNetworkAccessManager(this));
This will crash in the dtor when you don't add
m_manager = nullptr;
in there. No need for a shared_ptr here at all since it will automatically be deleted when the parent gets deleted.