2016-07-08 6 views
1

Ich habe zwei Klassen und will Meta-Informationen von der Unterklasse erhalten:Aufruf virtuelle Methode auf Unterklasse zurückgibt Super Daten

class DataObject : public QObject { 
    Q_OBJECT 
    ... 
    public: 
     virtual void meta() { 
      const QMetaObject *mo = QObject::metaObject(); 

      for (int i = 0; i < mo->propertyCount(); i++) { 
       qDebug() << mo->property(i).name() << mo->property(i).read(this); 
      } 
     } 
    ... 
} 

class User : public DataObject { 
    Q_OBJECT 
    Q_PROPERTY(int id MEMBER m_id) 
    ... 
} 

Als ich Meta rufe auf einem User Object es gibt nur die Standard-Objekteigenschaft objectName, nicht die Eigenschaften, die in der Benutzerklasse deklariert sind.

Kann ich die Metainformationen der Unterklassen irgendwie erhalten, ohne die Methode in jedem einzelnen von Hand zu implementieren?

Antwort

5

Sie benötigen metaObject() über dynamische Dispatch aufgerufen aufgerufen wird, nicht statisch (Class::method() ist statisch Versand). Sie brauchen auch nicht meta(), um virtuell zu sein, noch eine Methode - es sollte eine freistehende Funktion sein, es gilt für jedes Objekt, das Sie daran übergeben; C++ ist nicht Java.

Ein Beispiel folgt. Ausgang:

objectName QVariant(QString, "") 
id QVariant(int, 1) 
// https://github.com/KubaO/stackoverflown/tree/master/questions/meta-derived-38268004 
#include <QtCore> 

void meta(QObject * obj) { 
    auto mo = obj->metaObject(); 
    for (int i = 0; i < mo->propertyCount(); i++) 
     qDebug() << mo->property(i).name() << mo->property(i).read(obj); 
} 

struct DataObject : QObject { 
    Q_OBJECT 
}; 

struct User : DataObject { 
    Q_PROPERTY(int id MEMBER m_id) 
    Q_OBJECT 
    int m_id { 1 }; 
}; 

int main() { 
    User user; 
    Q_ASSERT(user.metaObject()->propertyCount() == 2); 
    meta(&user); 
} 

#include "main.moc" 
1

Sie rufen explizit QObject::metaObject() Methode, d. H. Methode der QObject Basisklasse. Entfernen QObject:: Teil von Ihrer meta() Implementierung und damit virtuelle Umsetzung von metaObject() wird zur Laufzeit