Anzeige:
Ergebnis 1 bis 6 von 6

Thema: const-correctness bei get-Methoden

  1. #1
    Registrierter Benutzer
    Registriert seit
    02.12.2005
    Ort
    Ebern
    Beiträge
    19

    const-correctness bei get-Methoden

    Hi,

    mir stellt sich gerade die Frage welche Art und Weise der Deklaration einer get-Methode denn überhaupt die sinnvollste ist.

    Um das ganz mal zu konkretisieren: Folgende, hier vereinfachte, Klasse:

    Code:
    class Shape {
    
        private:
            Color color;
    
        protected:
            Shape( Color const& _color) : color(_color) {}
    	virtual ~Shape() {}
    	virtual void draw() const = 0;
    
        public:
    
            void setColor(const Color & _color) { color = _color; }
    
            //Hier nun die Frage welche die richtige ist
            Color & getColor() { return color; }
            const Color*  getColor() { return &color; }
            const Color*  getColor() const { return &color; }
            const Color* const getColor()  { return &color; }
            const Color* const getColor() const { return &color; }
            const Color & getColor() const { return color; }
            const Color& getColor()  { return color; }
    };
    get-Methoden sollten ja eigentlich das Objekt nicht verändern, von dem Gesichtspunkt aus hätte ich
    const Color & getColor() const { return color; }
    genommen. Andererseits kann ich dann folgendes nichtmehr machen:
    Code:
    s->getColor().setR(255);
    Von daher würde ich denhier nehmen:
    Code:
    Color & getColor() { return color; }
    Allerdings kann ich mit dem dann wiederum in der draw()-Methode einer Abgeleiteten Klasse nicht getColor() aufrufen, weil draw() ja const ist und von daher dürfen keine nicht-const Methoden aufgerufen werden. Man könnte color in Shape auch public oder protected machen .... Ich bin im Moment total verwirrt. Wär echt toll wenn jemand Licht ins Dunkle bringen könnte.

  2. #2
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Je nach Komplexität eines Color Objekts würde ich eher sogar so schreiben
    (so wird das zum Beispiel auch durchgehend bei Qt gemacht)
    Code:
    Color color() const { return color; }
    sonst
    Code:
    const QColor& color() const { return color; }
    Und nachdem das eine abstrakte Klasse ist, color eher protected.
    Private bringt IMHO nur was, wenn damit eine wesentliche Invariante gesichert werden muss, die Entwickler von abgeleiteten Klassen eventuell nicht ganz richtig hinbekommen könnten.

    Der von dir angesprochene Anwendungsfall des direkten Methodenaufrufs am Memberobjekt ist zwar bequem, man muss dabei aber berücksichtigen, dass solche Änderungen an der umschließenden Klasse vorbei gehen.
    D.h. Shape bzw. eine Subklasse könnten auf eine etwaige Wertänderung nicht reagieren, weil sie ja nix davon mitkriegen.

    Ich persönlich mache das daher nur dann, wenn das optionale Einstellungen sind, die zu einem bestimmten bekannten Zeitpunkt ausgewertet werden.
    Beipiel
    Code:
    class HttpRequest
    {
    protected:
        MetaData m_MetaData;
    
    public:
       MetaData& metaData() { return m_metaData;}
    
       istream get() const; // nur get() benutzt die Werte von MetaData
    };
    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.12.2005
    Ort
    Ebern
    Beiträge
    19
    Ok, d.h. bei einfacher Komplexität:
    Code:
    Color color() const { return color; }
    bei höherer Komplexität:
    Code:
    const QColor& color() const { return color; }
    Richtig?
    Und
    Code:
    s->getColor().setR(255);
    würde dann ja nichtmehr gehen, also nurnoch
    Code:
    s->setColor(255, s->getColor()->getG(), s->getColor()->setB());
    wodurch das Shape-Objekt (bzw. Objekt einer Subklasse) wieder die Kontrolle über die Änderungen erhält.
    Habe ich dich soweit richtig verstanden?

    Grüße

  4. #4
    Administrator Avatar von anda_skoa
    Registriert seit
    17.11.2001
    Ort
    Graz, Österreich
    Beiträge
    5.477
    Zitat Zitat von miracoli Beitrag anzeigen
    Ok, d.h. bei einfacher Komplexität:
    Code:
    Color color() const { return color; }
    bei höherer Komplexität:
    Code:
    const QColor& color() const { return color; }
    Richtig?
    Korrekt.

    Und
    Code:
    s->getColor().setR(255);
    würde dann ja nichtmehr gehen, also nurnoch
    Code:
    s->setColor(255, s->getColor()->getG(), s->getColor()->setB());
    wodurch das Shape-Objekt (bzw. Objekt einer Subklasse) wieder die Kontrolle über die Änderungen erhält.
    Habe ich dich soweit richtig verstanden?
    Ja, oder
    Code:
    Color color = s->getColor();
    color.setR(255);
    s->setColor(color);
    Ciao,
    _
    Qt/KDE Entwickler
    Debian Benutzer

  5. #5
    Registrierter Benutzer
    Registriert seit
    02.12.2005
    Ort
    Ebern
    Beiträge
    19
    Vielen Dank!

    Gruß

  6. #6
    Registrierter Benutzer Avatar von panzi
    Registriert seit
    04.05.2001
    Ort
    Kottingbrunn
    Beiträge
    609
    Zitat Zitat von anda_skoa Beitrag anzeigen
    Je nach Komplexität eines Color Objekts würde ich eher sogar so schreiben
    (so wird das zum Beispiel auch durchgehend bei Qt gemacht)
    Code:
    Color color() const { return color; }
    Ja, aber weil viele (komplexe) Klassen in Qt das hier verwenden:
    http://doc.qtsoftware.com/4.5/qshareddatapointer.html

    Damit kann man implizite smart Pointer implementieren die eine copy-on-write Semantik verwenden. D.h. kopierst du ein solches Objeckt machst du in Wirklichkeit nur eine Kopie eines Pointer (+ref-count erhöhen). Erst bei der nächsten Schreiboperation wird tatsächlich eine Kopie erstellt. Wenn es nie eine solche gibt hat man natürlich den vorteil das auch nix Kopiert wird.
    Intel Core 2 Duo CPU 2.66GHz; Nvidia GeForce 8 8800 GTS; 4GB RAM; Fedora 12; KDE-testing

Lesezeichen

Berechtigungen

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