Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. German
  4. Frage zum Thema private implementation

Frage zum Thema private implementation

Scheduled Pinned Locked Moved Solved German
9 Posts 4 Posters 1.7k Views 2 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.
  • msauer751M Offline
    msauer751M Offline
    msauer751
    wrote on last edited by
    #1

    Hallo zusammen,
    um in das Thema QtQuick / QML zu kommen, hatte ich mir ein Buch aus dem packt Verlag besorgt. In diesem verwendet der Autor die private implementation Technik mit folgendem Beispiel:

    private:
        class Implementation;
        QScopedPointer<Implementation> implementation;
    

    in der Klassendefinition.

    Jetzt habe ich heut noch gelesen, dass es noch eine weitere Methode gibt:

    class GeoControllerPrivate;
        class LIBGEO_EXPORT GeoController : public QObject
        {
            Q_OBJECT
        Q_DECLARE_PRIVATE(GeoController);
        QScopedPointer<GeoControllerPrivate> const d_ptr;
    ...
    

    Gibt es denn eine Aussage, welche die richtige Methode ist? Gibt es im Netz eine Doku zu diesem Thema? Warum mache ich denn generell eine private Implementierung?

    Danke für Eure Hilfe.
    gruss
    martin

    aha_1980A 1 Reply Last reply
    0
    • TrzmielT Offline
      TrzmielT Offline
      Trzmiel
      wrote on last edited by
      #2

      Den Qt-Weg erklärt ein Artikel in der Wiki.

      @msauer751

      Gibt es im Netz eine Doku zu diesem Thema? Warum mache ich denn generell eine private Implementierung?

      Du findest sehr viel zu diesem Thema, wenn Du im Netz nach "d-zeiger idiom" oder "pimpl idiom" suchst.

      1 Reply Last reply
      4
      • msauer751M msauer751

        Hallo zusammen,
        um in das Thema QtQuick / QML zu kommen, hatte ich mir ein Buch aus dem packt Verlag besorgt. In diesem verwendet der Autor die private implementation Technik mit folgendem Beispiel:

        private:
            class Implementation;
            QScopedPointer<Implementation> implementation;
        

        in der Klassendefinition.

        Jetzt habe ich heut noch gelesen, dass es noch eine weitere Methode gibt:

        class GeoControllerPrivate;
            class LIBGEO_EXPORT GeoController : public QObject
            {
                Q_OBJECT
            Q_DECLARE_PRIVATE(GeoController);
            QScopedPointer<GeoControllerPrivate> const d_ptr;
        ...
        

        Gibt es denn eine Aussage, welche die richtige Methode ist? Gibt es im Netz eine Doku zu diesem Thema? Warum mache ich denn generell eine private Implementierung?

        Danke für Eure Hilfe.
        gruss
        martin

        aha_1980A Offline
        aha_1980A Offline
        aha_1980
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi, @msauer751

        Q_DECLARE_PRIVATE ist wie Q_OBJECT ein Makro. Such mal nach der Deklaraton und versuche sie zu verstehen.

        Warum treibt man den Aufwand: Binärkompatibilität.

        Wenn du einer Klasse Membervariablen hinzufügst, enfernst oder änderst müssen alle Nutzer neu compiliert werden. Mit PIMPL (pointer to private implementation) kann das vermieden werden.

        Grüsse

        Qt has to stay free or it will die.

        1 Reply Last reply
        3
        • msauer751M Offline
          msauer751M Offline
          msauer751
          wrote on last edited by
          #4

          Hi,

          danke Euch schonmal für die Infos.

          D.h. der Weg über class Implementation ist der allgemeine Weg und bei Verwendung von Qt kann alles einfacher über die Macros gemacht werden?

          gruss
          martin

          aha_1980A 1 Reply Last reply
          0
          • msauer751M msauer751

            Hi,

            danke Euch schonmal für die Infos.

            D.h. der Weg über class Implementation ist der allgemeine Weg und bei Verwendung von Qt kann alles einfacher über die Macros gemacht werden?

            gruss
            martin

            aha_1980A Offline
            aha_1980A Offline
            aha_1980
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @msauer751 Ja, das kann man so sagen.

            Grüsse

            Qt has to stay free or it will die.

            1 Reply Last reply
            0
            • msauer751M Offline
              msauer751M Offline
              msauer751
              wrote on last edited by
              #6

              So,
              habe jetzt mal meine Klasse auf Q_DECLARE_PRIVATE / Q_DECLARE_PUBLIC umgestellt. In dem privaten Teil würde ich gern ein Signal mit einem Slot verbinden. In der Public Funktion habe ich dazu das connect aufgerufen:

                  connect(d->qGeoCodeReply, SIGNAL(finished()), this, SLOT(searchDone()));
              

              Allerdings bekomme ich immer die Meldung,

              Object::connect: No such slot geo::GeoController::searchDone() in ../../lib-geo/source/controller/geo-controller.cpp:108.

              Hier mal mein Code:

              include.h:

              #ifndef GEO_H
              #define GEO_H
              
              #include <QObject>
              #include <QGeoServiceProvider>
              #include <QGeoAddress>
              #include <QGeoCodeReply>
              #include <QGeoLocation>
              #include <QGeoCodingManager>
              #include <QString>
              #include <QDebug>
              #include <QList>
              
              #include "lib-geo_global.h"
              #include "data/geo-point.h"
              
              namespace geo {
              
              class GeoControllerPrivate;
              
              class LIBGEO_EXPORT GeoController : public QObject
              {
                  Q_OBJECT
              
              public:
                  explicit GeoController(QObject *parent = nullptr);
                  ~GeoController();
              
                  void setOrt(const QString&);
                  void setHome(const QGeoCoordinate&);
                  void doSearch(void);
                  uint getCnt(void);
                  QList<data::GeoPoint*> getPointList(void);
              
                  bool Error;
              
              protected:
                  QScopedPointer<GeoControllerPrivate> const d_ptr;
              
              private:
                  Q_DECLARE_PRIVATE(GeoController);
              };
              
              }
              
              #endif // GEO_H
              

              source.cpp:

              #include "controller/geo-controller.h"
              
              namespace geo {
              
              class GeoControllerPrivate
              {
                  Q_DISABLE_COPY(GeoControllerPrivate)
                  Q_DECLARE_PUBLIC(GeoController)
              
              public:
                  GeoControllerPrivate(GeoController *parent)
                      : q_ptr(parent)
                      , qGeoService("osm")
                  {
                       pQGeoCoder = qGeoService.geocodingManager();
                       // qDebug() << ">> GeoController > Constructor (" << __LINE__ << ") error " << qGeoService.error() << ", errorstring " << qGeoService.errorString() << ", geocoding " << qGeoService.geocodingFeatures();
                       if (!pQGeoCoder) {
                           // qDebug() << ">> GeoController > Constructor (" << __LINE__ << ") GeoCodingManager not available!";
                           Error = true;
                       }
                  }
              
                  bool doSearch(void)
                  {
                      Error = false;
              
                      qGeoCodeReply = pQGeoCoder->geocode(qGeoAddress);
                      if (!qGeoCodeReply) {
                          // qDebug() << ">> GeoController > doSearch (" << __LINE__ << ") search failed!";
                          Error = true;
                      }
                      // else
                          // qDebug() << ">> GeoController > doSearch (" << __LINE__ << ") start search";
              
                      return Error;
                  }
              
                  GeoController           *const q_ptr;
                  QGeoServiceProvider     qGeoService;
                  QGeoCodingManager       *pQGeoCoder{nullptr};
                  QGeoAddress             qGeoAddress;
                  QGeoCodeReply           *qGeoCodeReply{nullptr};
                  QString                 Ort;
                  uint                    CntResult;
                  QGeoCoordinate          Home;
                  bool                    Error;
                  QList<data::GeoPoint*>  PointList;
              
              public slots:
                  void searchDone(void)
                  {
                      QList<QGeoLocation> Loc = qGeoCodeReply->locations();
                      CntResult               = Loc.count();
                      QGeoCoordinate      Temp;
                      data::GeoPoint      Point;
              
                      PointList.clear();
              
                      // qDebug() << ">> GeoController > searchDone (" << __LINE__ << ") " << qGeoCodeReply->isFinished();
                      // qDebug() << ">> GeoController > searchDone (" << __LINE__ << ") " << Loc.count();
              
                      for (uint i=0; i < CntResult; ++i) {
                          Temp = Loc.at(i).coordinate();
                          Point.Clear();
                          Point.setPoint(Temp);
                          if (Home.isValid()) {
                              Point.setAzimut(Temp.azimuthTo(Home));
                              Point.setDistance(Temp.distanceTo(Home) / 1000);
                          }
                          PointList.append(&Point);
                          // qDebug() << ">> GeoController > searchDone (" << __LINE__ << ") " << Temp << ", distance = " << Point.getDistance() << ", Azimut = " << Point.getAzimut();
                      }
                  }
              };
              
              GeoController::GeoController(QObject *parent)
                  : QObject(parent)
                  , d_ptr(new GeoControllerPrivate(this))
              {
              }
              
              GeoController::~GeoController()
              {
              }
              
              void GeoController::doSearch(void)
              {
                  Q_D(GeoController);
                  // qDebug() << ">> GeoController > doSearch (" << __LINE__ << ") suche nach Ort = " << d_ptr->Ort;
                  Error = d->doSearch();
                  connect(d->qGeoCodeReply, SIGNAL(finished()), this, SLOT(searchDone()));
              }
              
              }
              

              Könnte mir einer ein Tip geben, wie ich das mit den Signal / Slot in einer privaten Klasse mache.
              Danke schon mal.
              gruss
              martin

              1 Reply Last reply
              0
              • msauer751M Offline
                msauer751M Offline
                msauer751
                wrote on last edited by
                #7

                Ok. Wenn ich in bool doSearch (void) folgendes schreibe

                       QObject::connect(qGeoCodeReply, &QGeoCodeReply::finished, [=](){searchDone();});
                

                Funktioniert es. Allerdings habe ich keine Ahnung was ich da gemacht habe. (Lambda Funktionen sagen mir nichts).

                Habt Ihr eine Erklärung dafür?

                gruss
                martin

                J.HilkJ 1 Reply Last reply
                0
                • msauer751M msauer751

                  Ok. Wenn ich in bool doSearch (void) folgendes schreibe

                         QObject::connect(qGeoCodeReply, &QGeoCodeReply::finished, [=](){searchDone();});
                  

                  Funktioniert es. Allerdings habe ich keine Ahnung was ich da gemacht habe. (Lambda Funktionen sagen mir nichts).

                  Habt Ihr eine Erklärung dafür?

                  gruss
                  martin

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #8

                  @msauer751 said in Frage zum Thema private implementation:

                  Habt Ihr eine Erklärung dafür?

                  sicher,
                  in deiner Geo klasse hast du keine deiner Funktionen als SLOT definiert, Qt hat auch hierfür Makros.

                  deswegen die Meldung

                  Object::connect: No such slot geo::GeoController::searchDone() in ../../lib-geo/source/controller/geo-controller.cpp:108.
                  

                  searchDone ist nur eine normale Klassenfunktion, aber die alte Qt4 Syntax brauch die Makros.
                  Die neue Qt5 Syntax braucht diese nicht.
                  Du bist den extra (und hier unnötigen) Schritt gegangen und hast Qt5Connect Syntax mit einem Lambda verknüpft.

                  Lass es mich für dich vereinfachen:

                  Object::connect(qGeoCodeReply, &QGeoCodeReply::finished, this, &GeoController::searchDone);
                  

                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  msauer751M 1 Reply Last reply
                  3
                  • J.HilkJ J.Hilk

                    @msauer751 said in Frage zum Thema private implementation:

                    Habt Ihr eine Erklärung dafür?

                    sicher,
                    in deiner Geo klasse hast du keine deiner Funktionen als SLOT definiert, Qt hat auch hierfür Makros.

                    deswegen die Meldung

                    Object::connect: No such slot geo::GeoController::searchDone() in ../../lib-geo/source/controller/geo-controller.cpp:108.
                    

                    searchDone ist nur eine normale Klassenfunktion, aber die alte Qt4 Syntax brauch die Makros.
                    Die neue Qt5 Syntax braucht diese nicht.
                    Du bist den extra (und hier unnötigen) Schritt gegangen und hast Qt5Connect Syntax mit einem Lambda verknüpft.

                    Lass es mich für dich vereinfachen:

                    Object::connect(qGeoCodeReply, &QGeoCodeReply::finished, this, &GeoController::searchDone);
                    
                    msauer751M Offline
                    msauer751M Offline
                    msauer751
                    wrote on last edited by
                    #9

                    @J-Hilk

                    Der SLOT befindet sich als public slots (void searchDone(void)) in GeoCodePrivate.
                    Da GeoCodePrivate nicht von QObject abgeleitet ist, kann ich in der Funktion doSearch auch kein Connect aufrufen. Deswegen habe ich das connect in der Klasse GeoCode mit den Lambda ausdrücken.

                    gruss

                    martin

                    1 Reply Last reply
                    0

                    • Login

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