Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Signals
Forum Updated to NodeBB v4.3 + New Features

Signals

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 4 Posters 574 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    continue98
    wrote on last edited by
    #1

    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?

    1 Reply Last reply
    0
    • Axel SpoerlA Offline
      Axel SpoerlA Offline
      Axel Spoerl
      Moderators
      wrote on last edited by
      #2

      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.

      Software Engineer
      The Qt Company, Oslo

      1 Reply Last reply
      1
      • C Offline
        C Offline
        continue98
        wrote on last edited by
        #3

        @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

        JonBJ 1 Reply Last reply
        0
        • Axel SpoerlA Offline
          Axel SpoerlA Offline
          Axel Spoerl
          Moderators
          wrote on last edited by
          #4

          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.

          Software Engineer
          The Qt Company, Oslo

          1 Reply Last reply
          0
          • C continue98

            @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

            JonBJ Offline
            JonBJ Offline
            JonB
            wrote on last edited by JonB
            #5

            @continue98
            We don't know what your this is, nor what is in Request 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 the std::bind() is relevant to the problem here.

            C 1 Reply Last reply
            1
            • JonBJ JonB

              @continue98
              We don't know what your this is, nor what is in Request 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 the std::bind() is relevant to the problem here.

              C Offline
              C Offline
              continue98
              wrote on last edited by
              #6

              @JonB said in Signals:

              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) {
                
              }
              
              JonBJ Christian EhrlicherC 2 Replies Last reply
              0
              • C continue98

                @JonB said in Signals:

                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) {
                  
                }
                
                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #7

                @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.

                1 Reply Last reply
                1
                • C continue98

                  @JonB said in Signals:

                  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) {
                    
                  }
                  
                  Christian EhrlicherC Online
                  Christian EhrlicherC Online
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @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.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  1

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved