Datenelement in Basisklasse oder virtuelle Methode



  • Hallo zusammen,

    nehmen wir an, ich habe eine Basisklasse und alle davon abgeleiteten Klassen sollen eine TypID zurückgeben können.
    Ob das sinnvoll ist oder nicht - darüber kann man sich streiten, mir ist aber gerade kein besseres Beispiel eingefallen.

    Was würdet ihr dann bevorzugen?

    Gleicher Code:

    namespace IDs
    {
      enum Type
      {
         Derived1ID, Derived2ID, ...;
      };
    }
    

    1. Variante)

    class Base
    {
    public:
      Base(int id):
      id_(id){}
      virtual ~Base(){}
    
      Ids::Type getID() const {return id_;}
    
    private:
      int id_;
    };
    
    class Derived1 : public Base
    {
    public:
      Derived1():
      Base(IDs::Derived1ID){}
    };
    

    2. Variante)

    class Base
    {
    public:
      virtual ~Base(){}
      virtual IDs::Type getID() const = 0;
    };
    
    class Derived1 : public Base
    {
    public:
      virtual IDs::Type getID() const
      {return IDs::Derived1ID;}
    };
    

    Was auf die Schnelle auffällt:
    - Bei der zweiten Variante wird minimal Speicherplatz gespart
    - Bei der zweiten Variante können von Derived1 abgeleitete Klassen die ID weiter ändern
    - Bei der ersten Variante ist der Methodenaufruf nicht virtuell

    Mir ist häufig die erste Variante in ähnlichen Situationen begegnet.

    Was meint ihr - was ist besser und warum?



  • Die erste ist in der Verwendung schneller. Aber wenn ich sowas brauche, mache ich entweder die zweite Variante und auf Speed kommt's nicht an, denn die zweite ist viel unärgerlicher wenns um mehrere Ebenen geht. Oder ich mache es compilerspezifisch.



  • Ich denk, das bissi Geschmacks-Sache.

    Bei Variante 1 konntest mehr mit den Zugriffsbeschraenkungen ueber die Construktoren machen.
    Base kann niemals allein erzeugt werden, der CTor mit der ID kann deshalb protected werden.
    Genau so koennt man Derived1 auch nen protected Ctor verpassen, den weitere Ableitungen dann benutzen sollten ...

    Und wenn du oft in der Basis Zugriff auf Die ID brauchst, hasst du Member vs. vtable aufruf. Mit dem Member dürft er vielleicht kleinwenig schneller sein.

    Und sicher das du sparst bei version 2 ?
    Du hasst einen eintrag mehr in der vtable ....

    Ciao ...



  • Die Vtable liegt doch nur einmal pro klasse im Speicher, die attribute aber einmal pro Objekt, also vom Speicher her denke ich, spart man wirklich, wird aber kaum relevant sein.


  • Mod

    Q schrieb:

    Die Vtable liegt doch nur einmal pro klasse im Speicher, die attribute aber einmal pro Objekt, also vom Speicher her denke ich, spart man wirklich, wird aber kaum relevant sein.

    Aber dafür hat jedes Objekt hat einen Verweis auf den vtable als versteckten Member.



  • Das ist schon klar, aber den habe ich sowieso.
    Bei beiden Varianten hat die Basisklasse einen virtuellen Destruktor.

    Und natürlich dauert es minimal länger eine virtuelle Methode aufzurufen, als eine normale, aber halt nur minimal.

    Naja ich glaub inzwischen sind wir ein wenig abgeschweift, im Prinzip ist ja alles geklärt, scheint wohl keine wirklich bessere Variante zu geben, beide sind wohl ungefähr gleich gut (evtl. je nach situation).


Anmelden zum Antworten