Klassendefinition beim kompilieren kopieren und ändern

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Klassendefinition beim kompilieren kopieren und ändern

Beitrag 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!
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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".
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Normalerweise ist das Sache des Editors.
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag 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
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wenn alles gleich ist - was ist dann der Sinn der unterschiedlichen Klassen??
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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();
}
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag 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
gk_17
Beiträge: 37
Registriert: 4. Oktober 2009 19:20

Beitrag 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?
dazedly
Beiträge: 197
Registriert: 3. Oktober 2010 15:38
Kontaktdaten:

Beitrag von dazedly »

Ist ja lustig mit den Smileys, passend zur Stimmung? :) Ne du kannst leider kein Q_OBJECT in Templates benutzen.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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?
Antworten