Unterschiede Vererbung/Instanziierung von struct



  • Hallo,

    Frage:

    Was sind Unterschiede, Vor- Nachteile, ect. zwischen folgenden Implementierungen auch im Hinblick auf Vererbung:

    struct A
    {
     long lWert;
    }
    
    Class CA: private A
    

    und

    struct A
    {
     long lWert;
    }
    
    Class CA:
    {
    private:
    A m_strA;
    }
    

    Mir erscheint eine private Membervariable "sauberer".
    Meinungen dazu?



  • MFC-Coder schrieb:

    Mir erscheint eine private Membervariable "sauberer".
    Meinungen dazu?

    ja: rembrand?
    ­čśĽ



  • Hallo,

    die Frage an sich ist nicht wirklich korrekt, weil beide Dinge eigentlich nichts miteinander zu tun haben. D.h. du nimmst entweder das eine wenn du das eine brauchst, oder du nimmst das andere wenn du das andere brauchst.

    - Private Vererbung bedeutet is implemented in terms of .
    - Eine private Membervariable stellt eine has-a Beziehung dar.

    Also nimmst du eine private Membervariable, wenn dein Datentyp ein Member is haben soll. Du nimmst private Vererbung, wenn du deinen Datentyp auf Basis von etwas aufbauen willst, z.b. noncopyable .



  • edit: Irgendwie verschrieben

    out schrieb:

    ...Also nimmst du eine private Membervariable, wenn dein Datentyp ein Member is haben soll...

    Also nimmst du eine private Membervariable, wenn dein Datentyp einen Member X haben soll.


  • Mod

    out schrieb:

    Du nimmst private Vererbung, wenn du deinen Datentyp auf Basis von etwas aufbauen willst, z.b. noncopyable .

    Zuf├Ąllig etwas ung├╝nstiges Beispiel, weil noncopyable als Member genausogut funktioniert. Hier steht bei der Vererbung eher der deklaratorische Wert im Vordergrund. Und noncopyable implementiert ja gerade nicht...



  • camper schrieb:

    bei der Vererbung eher der deklaratorische Wert im Vordergrund. Und noncopyable implementiert ja gerade nicht...

    Kannst du das genauer spezifizieren? Eventuell ein sinnvolles Beispiel machen?
    Ich w├Ąre jetzt z.B. nicht auf die Idee gekommen, noncopyable via has-a zu realisieren, ich find es es gut wie boost es macht. ­čÖé



  • Ein Typ ist nicht kopierbar, wenn ein Member von ihm nicht kopierbar ist...



  • theta schrieb:

    Ein Typ ist nicht kopierbar, wenn ein Member von ihm nicht kopierbar ist...

    Ja, ich meinte was anderes. Ich fragte nach einem Beispiel, wo private Vererbung wirklich sinnvoll ist, und was camper mit "deklaratorische Wert im Vordergrund" genau meint. ­čÖé



  • camper schrieb:

    Zuf├Ąllig etwas ung├╝nstiges Beispiel, weil noncopyable als Member genausogut funktioniert. Hier steht bei der Vererbung eher der deklaratorische Wert im Vordergrund.

    Prinzipiell l├Ąsst sich jede private Vererbung ├╝ber Member umsetzen, wenn der besagte Typ nicht virtuell ist, sogar ohne Zusatzklassen. Der Grund f├╝r private Vererbung kann Schreibaufwand sparen (bei boost::noncopyable do_not_copy_this_class; der Variablennamen), der deklaratorische Wert class X : boost::noncopyable lies: "class X is noncopyable") oder -- hier wohl der Hauptgrund -- EBO sein (wer w├╝rde boost::noncopyable ohne EBO verwenden?). Eine Alternative w├Ąre ihn in std::tuple zu speichern, aber der Platz ist zu wenig prominent.

    Insofern finde ich boost::noncopyable das ein gutes Beispiel.



  • out schrieb:

    Ich fragte nach einem Beispiel, wo private Vererbung wirklich sinnvoll ist

    Stichwort "NVI".

    Private Vererbung ist dann notwendig, wenn in der Basisklasse das "Non Virtual Interface" angewendet wird:

    class Base
    {
      public:
        int Calculate()
          {
            if (DoCalculate())
              return 1;
    
            return 0;
          }
    
      private:
        virtual bool DoCalculate() = 0;
    };
    
    class Derived : private Base
    {
      virtual bool DoCalculate()
        {
          return true;
        }
    };
    


  • Bei NVI nimmt man public Vererbung.



  • Kellerautomat schrieb:

    Bei NVI nimmt man public Vererbung.

    Warum?



  • daddy_felix schrieb:

    Kellerautomat schrieb:

    Bei NVI nimmt man public Vererbung.

    Warum?

    Die Frage l├Ąsst sich auch in die Gegenrichtung stellen:
    Warum die ├Âffentliche Schnittstelle der Basisklasse in diesem Fall nicht auch f├╝r die abgeleiteten Klassen anbieten? Warum sollte man in deinem Beispiel "Calculate" nicht direkt auf der abgeleiteten aufrufen k├Ânnen?

    Private Vererbung halte ich eher dann f├╝r sinnvoll wenn man ein funktionelle Vererbung haben, aber nicht nach au├čen die gleiche Schnittstelle anbieten will.



  • asc schrieb:

    Warum sollte man in deinem Beispiel "Calculate" nicht direkt auf der abgeleiteten aufrufen k├Ânnen?

    weil es sich um ein einfaches Beispiel zum NVI handelt, wo ich nicht mehr Gehirnschmalz als unbedingt n├Âtig reinstecken wollte.

    "Calculate" darf nicht direkt aufgerufen werden, weil "Derived" erst einen Mutex setzen muss. Und bevor wieder gemeckert wird: Klar, k├Ânnte man den Mutex auch in Base setzen. Aber wenn Base zu einer externen Lib geh├Ârt, l├Ąsst sich das nicht ├Ąndern.

    oder

    Es ergibt keinen Sinn, "Calculate" von au├čen aufzurufen, weil Base als Timer implementiert ist, der periodisch pr├╝ft, ob die abgelaufene Zeit einen Schwellenwert ├╝berschreitet und wenn ja, die private Funktion aufruft.

    Klar k├Ânnte man das alles sicher auch anders modellieren. Aber nur, weil mir jetzt keine 100% ├╝berzeugenden Beispiele einfallen, muss das Konzept ja nicht prinzipiell schlecht sein. Oder gibt es gute Gr├╝nde, warum NVI immer public sein sollte?

    edit:

    asc schrieb:

    Private Vererbung halte ich eher dann f├╝r sinnvoll wenn man ein funktionelle Vererbung haben, aber nicht nach au├čen die gleiche Schnittstelle anbieten will.

    genau. Und ich will die Funktion von "Base" nuzten und intern "Calculate" aufrufen, ohne diese Schnittstelle nach au├čen anzubieten.


Log in to reply