Seite 1 von 1
Was mach das Makro Q_D()?
Verfasst: 30. Juni 2006 10:55
von kugelfisch
Hallo,
kann mir jemand erklähren, was Q_D() macht? Von welchem Typ ist die Variable "d" in QModelDir ?
QModelDir.cpp
Code: Alles auswählen
QDirModel::QDirModel(const QStringList &nameFilters,
QDir::Filters filters,
QDir::SortFlags sort,
QObject *parent)
: QAbstractItemModel(*new QDirModelPrivate, parent)
{
Q_D(QDirModel);
// we always start with QDir::drives()
d->nameFilters = nameFilters.isEmpty() ? QStringList("*") : nameFilters;
d->filters = filters;
d->sort = sort;
d->root.parent = 0;
d->root.info = QFileInfo();
d->clear(&d->root);
}
qglobal.h
Code: Alles auswählen
#define Q_DECLARE_PRIVATE(Class) \
inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr); } \
inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(d_ptr); } \
friend class Class##Private;
#define Q_D(Class) Class##Private * const d = d_func()
Gruß
Alex[/code]
Verfasst: 30. Juni 2006 14:13
von kugelfisch
Ah ich glaub ich habs. d ist ein Pointer auf eine Instanz der Klasse QDirModelPrivate - richtig?
Aber wo steckt da der Sinn dahinter?
Verfasst: 30. Juni 2006 15:08
von Christian81
Der sinn ist einfach - mann muss nicht so viel schreiben - Q_D() wird überall im Qt-Code verwendet. So weiss man immer gleich was gemeint ist.
Verfasst: 9. Juli 2006 01:11
von Eltharion
Ich glaube, es war die Frage nach dem Sinn der Trennung in Klassen und zugehörige Private-Klassen. Ich versuche mal eine Antwort zu geben, obwohl ich dabei sicherlich auch Fettnäpfchen erwischen werde. Ich bitte um eine rege, objektive Diskussion.
Einen wirklichen Sinn der ...Private-Klassen gibt es nicht, da man eigentlich auch via public/protected/private die Zugriffsrechte für Qt-interne Dinge setzen könnte. So wird die (Qt)Klasse zusätzlich noch in einen Private-Part und einen offiziellen Part geteilt und das ist m.E. nicht so toll, da man an die Private-Sachen später (ausserhalb von Qt) nicht mehr (oder nur noch sehr schlecht) ran kommt. Die Klasse wird API-mässig fixiert und ist später durch einfaches Ableiten oft nicht mehr sinnvoll erweiterbar. Die Erfinder wollten damit wohl verhindern, dass man in eigenen Programmen auf Qt-interne Daten oder Methoden zugreift oder zugreifen möchte. Normalerweise muss man das auch nicht, aber es gibt Situationen, wo man das schön wäre und ärgert sich dann darüber.
Man leitet z.B. eine Qt-Klasse ab und möchte ein exotischeres Feature dieser Klasse erweitern oder abändern und stellt fest, dass die zugehörigen Methoden der Qt-Klasse wiederum mit einer Klasse/Instanz namens QXyzPrivate interagieren, was die QXyz-Klasse problemlos darf, die davon abgeleitete Klasse aber nicht mehr. Das wird absolut nervig, wenn mehrere Klassen im Spiel sind, die sich gegenseitig aufrufen (oder wo eine Klasse eine Instanz der anderen erzeugt) oder sich gegenseitig via friend Rechte einräumen.
Damit erlauben die Trolltech-Programmierer zwar die Nutzung Ihrer Klassen, aber blockieren effizient die Erweiterung der API und die Erweiterung der Funktionalität der eigenen Klassen. Man versuche nur mal, z.B. die QTabBar um Drag- und Drop-Funktionen für Tabs oder um Interaktionen (Loslösen und Fallenlassen) von Tab-Inhalten und DockWindows zu erweitern. Wäre toll, wenn das einfach so ginge, aber man wird bei der Implementation durch die Trennung der API-Funktionen und der internen Hilfs-Funktionen dazu gezwungen, die Klassen zu nehmen und neu zu implementieren. Unter einem neuen Klassen-Namen und möglichst auch mit völlig neuem Code. Wiederverwertung von Code durch Ableiten wird unterbunden und ist nur den Trollen selbst erlaubt. Andere haben gefälligst das Rad neu zu erfinden oder grosse Teile der Klassen zu kopieren und dadurch auf die Vorteile der OO-Programmierung zu verzichten.
Für die Programmierer bringt es keine Vorteile. Einzig der Nutzer kann sich zufrieden zurücklehnen, denn wo z.B. Qt4 dran steht, ist auch Qt4 drin und ein Qt4-Programm kann problemlos gegen Qt4-Libs gelinkt werden. Der Programmierer muss das ausbaden. Der Sinn ist denke ich das Verhindern des Entstehens von Konkurrenz-Bibliothekten durch Verbesserung der eigenen Bibliothek, es ist also quasi ein Kopierschutz, der hart in den Quelltext eingebaut ist und das Aufkommen von Konkurrenz (durch bessere Qt-Ableger) welche auf der eigenen (aus Troll-Sicht) Arbeit (im Wesentlichen der Qt-Lib) basiert, verhindert.
Wenn man es genau nimmt, wird dadurch sogar der Quelltext aufgeblähter, unaufgeräumter/undurchschaubarer (mehr Einarbeitezeit, neue interne Makros, nicht wirklich notwendige ..Private-Klassen) und ineffizienter (da tlw. Aufrufe von Methoden einer Klasse an die der ..Private-Klasse weitergeleitet werden). Alles unnützer Kram, der bei einer konsequent-freien Implementierung entfallen könnte.
Einen Vorteil für den Nutzer der Klassen sehe ich, denn dieser wird in der Hilfe und beim Auto-Vervollständigen mittels Tab von vielen Optionen verschont und kann daher schneller seine Auswahl treffen, da die Anzahl der Methoden und Features abnimmt. Das könnte man aber mit einer guten Namenswahl der Funktionen auch erreichen.
E*
Verfasst: 9. Juli 2006 09:58
von Christian81
Ein weiterer Vorteil ist, dass man im Header ggf. weniger Includes braucht und dass man bei Änderungen an einer privaten Varaible (z.B. hinzufügen/entfernen) nicht alles neu kompilieren muss was diesen Header includiert
-> das Kompilieren geht schneller.
Verfasst: 11. Juli 2006 22:54
von Uwe
Christian81 hat geschrieben:Ein weiterer Vorteil ist, dass man im Header ggf. weniger Includes braucht und dass man bei Änderungen an einer privaten Varaible (z.B. hinzufügen/entfernen) nicht alles neu kompilieren muss was diesen Header includiert
-> das Kompilieren geht schneller.
Es geht natürlich auch um die Binärkompatibilität der Qt Bibliothek. Bei Änderungen im Private Teils zerbricht die nicht.
Der Performance Gewinn mit schlanken Header ist übrigens erheblich. Ich erinnere mich an die Portierung einer Applikation von Qt1 nach Qt2, bei der die Übersetzungszeiten von ca. 7 Minuten auf über 20 Minuten hochgingen. Die Qt3 Header waren diesbezüglich ebenfalls schlecht entworfen: mit ein paar Patches konnte man die Übersetzungszeiten deutlich senken.
Erst mit Qt4 hat TrollTech dieses Problem ernsthaft verfolgt und die Übersetzungszeiten sind wieder deutlich besser.
Uwe