Anzeige:
Ergebnis 1 bis 15 von 25

Thema: Probleme mit abgeleiteten Klassen

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Code:
    void MainWidget::loadDocument( QString absolute_document_path ){
    
            ...
    	setDocumentClass();
            ...
    		mask->fill(document->getFileContent(), document->getFileInfo());
            ...
    }
    
    void RecipeMask::fill( QString file_content, QFileInfo fileinfo ){
            ...
    	//////////////////////
    	// get preparation  //
    	//////////////////////
            ...
    	        this->preparation_te->setText( exp.cap(1) );
            ...
    }
    Preparation ist nur in der abgeleiteten Klasse RecipeMask enthalten. Vom Methodenaufruf unterscheidet sich der Code nicht.

    Natürlich kann man jetzt sagen, das man eine SuperMaske hätte erstellen können und je nach Anwendungsfall die Members darstellen und auswerten.
    Code:
    class BookMask: public Mask{
            ...  
    	QTextEdit              *description_te;
            ...
    }
    
    class RecipeMask: public Mask{
            ...  
    	QTextEdit              *description_te;
            ...
    }
    Doch finde ich es so viel übersichtlicher.
    Geändert von dml (27-01-2014 um 10:16 Uhr)

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Aber die Methode fill() ist doch bereits in Mask deklariert (virtual) und wird von den Subklassen nur anders implementiert.

    D.h. der Aufruf in MainWidget::loadDocument() wird bereits durch den Polymorphismus auf den jeweiligen Code umgeleitet.

    Code:
    Mask *mask = new RecipeMask;
    
    mask->fill(...); // Aufruf von RecipeMask::fill();
    
    mask = new BookMask;
    
    mask->fill(...); // Aufruf von BookMask::fill();
    Für den Aufruf von fill() ist es bedeutungslos auf welche Subklasse mask gerade veweißt, zur Laufzeit wird die Implementierung der jeweiligen Subklasse ausgeführt.

    Wenn wir diesen Codeschnippsel kurz umschreiben
    Code:
    switch (doctype) {
        case RECIPE:
            mask = new RecipeMask;
            break;
    
        case BOOK:
            mask = new BookMask;
            break;
    }
    
    mask->fill(...);
    dann ist im Falle von doctype == RECIPE in der letzten Zeile ein Aufruf von RecipeMask::fill(), im Falle von doctype == BOOK ein Aufruf von BookMask::fill(), usw.

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    In der Hoffnung Dich nicht inzwischen zu Nerven.
    Du hattest Recht der QDebug Befehl gibt Mask( , name="RecipeMask") herraus, ist also weiterhin vom Typ Mask.
    Das bringt mich zu dem Problem:
    Code:
    Document::saveDocument( Mask *mask );
    RecipeDocument::saveDocument( RecipeMask *rmask );
    aufgrund seines Parameters kann ich die Methode nicht als virtual deklarieren und so wird Document::saveDocument ausgeführt. Hast Du dafür vielleicht einen kleinen Tip für mich? Oder sollte ich dann doch besser eine große Maske erstellen die kleine Probleme mehr bereitet?
    Bzw: Wenn ich Maske wieder in Document einfüge muss ich eine Menge leerer virtueller Methoden in der Basisklasse schreiben, damit der Compiler alle Methoden der abgeleiteten Klassen akzeptiert.
    Geändert von dml (27-01-2014 um 16:45 Uhr)

  4. #4
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zitat Zitat von dml Beitrag anzeigen
    In der Hoffnung Dich nicht inzwischen zu Nerven.
    Nope, find ich cool

    Zitat Zitat von dml Beitrag anzeigen
    Das bringt mich zu dem Problem:
    Code:
    Document::saveDocument( Mask *mask );
    RecipeDocument::saveDocument( RecipeMask *rmask );
    Am ehesten so
    Code:
    class Document
    {
    public:
        virtual void saveDocument( Mask *mask ) = 0;
    };
    Code:
    class RecipeDocument : public Document
    {
    public:
        void saveDocument( Mask *mask ) = 0;
    };
    
    void RecipeDocument::saveDocument( Mask *mask )
    {
        RecipeMask *ourMask = dynamic_cast<RecipeMask*>( mask );
        if ( ourMask == 0 ) {
            // mask not of our type, log error or tell user, etc.
            return;
        }
    
        // use ourMask
    }
    Wenn Mask direkt oder indirekt von QQbject abgeleitet ist, kann man statt dynamic_cast auch qobject_cast benutzen.

    Zitat Zitat von dml Beitrag anzeigen
    Bzw: Wenn ich Maske wieder in Document einfüge muss ich eine Menge leerer virtueller Methoden in der Basisklasse schreiben, damit der Compiler alle Methoden der abgeleiteten Klassen akzeptiert.
    Ich kann mich jetzt nicht mehr so gut an den vollständigen Code erinnern, aber wenn Document die jeweiligen Daten enthält bzw bearbeitet und Mask die entsprechende GUI ist, könnte es eventuell andersrum besser gehen.

    D.h. wenn die jeweilige Mask sich ein entsprechendes Document erzeugt und hält.

    Generell müssen Methoden in der Basisklasse nicht "leer" implementiert werden, wenn sie von allen Subklassen ohnehin verschieden implementiert werden müssen. In diesen Fällen reicht es, die Methoden als "pure virtual" zu deklarieren, also virtual vorne und = 0 hinten.

    Das Ziel dabei ist, dass im Rest des Programms möglichst wenig, idealweise gar nicht, zwischen den Subklassen unterschieden werden muss, sondern das durch den Mechanismus des Methodenüberschreibens intern gehandhabt wird,

    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  5. #5
    Registrierter Benutzer
    Registriert seit
    02.08.2008
    Beiträge
    177
    Ich kann nur sagen Perfekt, vielen Dank! Jetzt wo es da steht ist es so logisch, doch bin ich nicht darauf gekommen. Ich hätte leere virutal methode() in die Basisklasse geschrieben, was nicht dem Sinn der Ableitung entstprochen hätte.
    = 0; funktioniert hierbei nicht, denn die Methode der Basisklasse garantiert, das Objekte (Name, Buchtitlel, Kategorien,...) die für das Funktionieren des Documentes unabdingbar sind, enthalten sind.

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •