Seite 1 von 1

Klassendefinition beim kompilieren kopieren und ändern

Verfasst: 3. Januar 2011 19:58
von gk_17
Hallo Leute,

ich habe eine grundsätzliche Frage, bei der ich nicht mal weiß, wonach ich suchen soll in Büchern. Vielleicht hat ja jemand einen Tipp, ein Stichwort?

Ich leite eine Klasse ab, um einige Methoden zu überschreiben:

Code: Alles auswählen

class MyCleanlooksStyle : public QCleanlooksStyle
{
    Überschreiben einiger Methoden, ziemlich viel lästige Arbeit...
    MyCleanlooksStyle::standardIcon()...
}
Jetzt brauche ich weitere neue Klassen, von anderen Klassen abgeleitet, die aber alle den bis auf den Klassennamen identischen Inhalt wie die erste haben:

Code: Alles auswählen

class MyPlastiqueStyle : public QPlastiqueStyle
{
   MyPlastiqueStyle::standardIcon()...
}
Ich kann das natürlich einfach kopieren, per Suchen/Ersetzen editieren und fertig. Ich will das aber nicht jedesmal machen, wenn ich etwas geändert habe. Gibt es eine Möglichkeit, eine Beispielklasse zu implementieren und alle anderen daraus automatisch zu erstellen?

Vielen Dank für eure Tipps!

Verfasst: 4. Januar 2011 07:47
von franzf
Was ist der genaue Hintergrund? Denn eine automatisierte Deklaration bringt nicht so viel, implementieren musst du das ja schon noch selber. Oder ist die Implementierung auch identisch bei allen Klassen? (Wäre arg komisch...)

Ein erster Ansatz wären Macros. Das Macro deklariert dir alle nötigen Member-Funktionen, so wie auch "Q_OBJECT".

Verfasst: 4. Januar 2011 08:59
von upsala
Normalerweise ist das Sache des Editors.

Verfasst: 4. Januar 2011 12:40
von gk_17
ja, es geht um eine automatische Deklaration und Implementierung. Ich benötige einige Klassen mit gleichem Text in Deklarierung und Implementierung, einzige Unterschiede werden die Klassennamen sein.

Weil ich aber darin ändern werde, möchte ich nicht jedesmal die geänderten Inhalte in alle anderen Dateien kopieren.

Ich kenne keine C++ Methode, wie Mehrfachvererbung oder ähnliches, kann mir auch fast nicht vorstellen, dass es da was gibt. Aber vielleicht gibt es irgendwelche beim bzw. vorm kompilieren anzustoßenden Makros, Skripte o.ä., die mir die Kopien erstellen?

Grüße,
gk_17

Verfasst: 4. Januar 2011 12:48
von Christian81
Wenn alles gleich ist - was ist dann der Sinn der unterschiedlichen Klassen??

Verfasst: 4. Januar 2011 13:28
von franzf
Wenn FAST alles gleich sein soll, gibts schon was:
templates + typedef + Spezialisierung :P
Hab grad nicht viel Zeit, wenns nicht klar ist frag nach, dann gibts später ein Beispiel.

Verfasst: 4. Januar 2011 18:37
von franzf
Ok, hier das angedrohte Beispiel:

Code: Alles auswählen

#include <iostream>
using namespace std;

class StyleA {
public:
    virtual void doA() {
        cout << "StyleA::doA()" << endl;
    }
    
    virtual void doB() {
        cout << "StyleB::doB()" << endl;
    }
};

class StyleB {
public:
    virtual void doA() {
        cout << "StyleB::doA()" << endl;
    }
    
    virtual void doB() {
        cout << "StyleB::doB()" << endl;
    }
};

template <typename BaseClass>
class MyStyle : public BaseClass {
public:
    virtual void doA() {
        cout << "MyStyle::doA()" << endl;
        BaseClass::doA();
    }
    
    virtual void doB() {
        cout << "MyStyle::doB()" << endl;
        BaseClass::doB();
    }
};

template<>
void MyStyle<StyleB>::doA() {
    cout << "Special MyStyle::doA()" << endl;
    StyleB::doA();
}

typedef MyStyle<StyleA> MyStyleA;
typedef MyStyle<StyleB> MyStyleB;

int main() {
    MyStyleA sa;
    MyStyleB sb;
    sa.doA();
    sa.doB();
    sb.doA();
    sb.doB();
}

Verfasst: 8. Januar 2011 11:36
von gk_17
Hallo franzf,

ich glaube, Dein Beispiel ist die Lösung! :)
Ich werde es mal implementieren und ausprobieren und dann nochmal Bescheid geben, ob es funktionierte.

@ Christian81
Es geht darum, die verschiedenen Style-Klassen von Qt (z.B. QPlastiqueStyle, QCleanlooksStyle, ...), die letztlich alle das gleiche machen, dazu zu bringen, einige der Standard-Buttons mit meinem selbst erstellten Icon anzuzeigen. Nach Lesen der Qt-Dokumentation meine ich verstanden zu haben, dass ich dazu einfach den slot standardIconImplementation() überschreiben muss. Der neue Inhalt dieses slots wäre dann aber für jede Ableitung eines Basis-Styles gleich, so in der Art: "Du willst Icon 24? nimm dieses dafür (mein eigenes)". Wenn ich jetzt mehrere der Basis-Styles anpassen möchte, muss ich jeden Style ableiten und den slot implementieren. Ist alles kein Problem, ich fragte mich nur, ob ich später bei Änderungen wie z.B. einem nochmaligen Austausch des Icons wieder jede Ableitung bearbeiten muss oder ob sowas eleganter geht.

Grüße,
gk_17

Verfasst: 9. Januar 2011 11:46
von gk_17
Leider kriege ich es nicht richtig hin, das Q_OBJECT-Makro verursacht Probleme
Hier ist der Beispielcode, einfach in main.cpp implementiert:

Code: Alles auswählen

#include<QPlastiqueStyle>

template <class BaseClass> class MyStyle : public BaseClass
{
Q_OBJECT
	protected slots:
		QIcon standardIconImplementation(QStyle::StandardPixmap standardIcon, const QStyleOption* option = 0, const QWidget* widget = 0) const
		{
			if(standardIcon == QStyle::SP_DialogOkButton)	
				return QIcon(QPixmap(":/icons/32x32/dialog_ok_apply.png"));
			else
			{
				return QIcon(BaseClass::standardPixmap(standardIcon, option, widget));
			}
		}
};

typedef MyStyle<QPlastiqueStyle> WeightPlastiqueStyle;

int main(int argc, char *argv[])
{	
	WeightPlastiqueStyle wps;
...
Ich bekomme folgenden linker-Fehler:
  • debug/main.o:(.rodata._ZTV7MyStyleI15QPlastiqueStyleE[vtable for MyStyle<QPlastiqueStyle>]+0x10): undefined reference to `MyStyle<QPlastiqueStyle>::metaObject() const'
    debug/main.o:(.rodata._ZTV7MyStyleI15QPlastiqueStyleE[vtable for MyStyle<QPlastiqueStyle>]+0x18): undefined reference to `MyStyle<QPlastiqueStyle>::qt_metacast(char const*)'
    debug/main.o:(.rodata._ZTV7MyStyleI15QPlastiqueStyleE[vtable for MyStyle<QPlastiqueStyle>]+0x20): undefined reference to `MyStyle<QPlastiqueStyle>::qt_metacall(QMetaObject::Call, int, void**)'
    collect2: ld returned 1 exit status
Wenn ich Q_OBJECT entferne, wird alles erfolgreich erstellt, der slot funktioniert nur nicht.
Habt ihr noch eine Idee?

Verfasst: 9. Januar 2011 11:58
von dazedly
Ist ja lustig mit den Smileys, passend zur Stimmung? :) Ne du kannst leider kein Q_OBJECT in Templates benutzen.

Verfasst: 9. Januar 2011 13:38
von franzf
Nachdem ich deineBegründung gelesen hab, seh ich dass das eh der falsche Weg ist.
Google mal nach "Qt4 Proxy Style".
// edit: Und das Q_OBJECT brauchst du eh nicht, du willst ja keine eigenen SIGNALS oder SLOTS deklarieren, oder?