protected Member / protected Vererbung



  • Hacker schrieb:

    Wenn ich sie nicht als protected deklariere, dann können sie nur public sein (um sie vererbbar zu machen) (oder Setter/Getter haben, was aber IMHO unschön ist), was wiederum nicht im anfänglichen Sinne war. Also ist protected die Lösung. Oder bin ich etwa wieder doof 😕

    Das Problem ist nicht wie man die Member "vererbbar macht", sondern dass du sie überhaupt "vererbbar machen" willst...



  • Man könnte ein "Interface" für erbende Klassen basteln, z.B so:

    class Game {
        public:
            void update();
        protected:
            virtual void Init(GAMEMODE gm);
            virtual void AddObject(Object);
            virtual void RemoveObject(Object);
        private:
            Timer timer;
            std::vector<Objects> objects;
    };
    


  • dot schrieb:

    Hacker schrieb:

    Wenn ich sie nicht als protected deklariere, dann können sie nur public sein (um sie vererbbar zu machen) (oder Setter/Getter haben, was aber IMHO unschön ist), was wiederum nicht im anfänglichen Sinne war. Also ist protected die Lösung. Oder bin ich etwa wieder doof 😕

    Das Problem ist nicht wie man die Member "vererbbar macht", sondern dass du sie überhaupt "vererbbar machen" willst...

    Bitte!? Ist das jetzt unüblich geworden, VERERBUNG zu benutzen?



  • Hacker schrieb:

    dot schrieb:

    Hacker schrieb:

    Wenn ich sie nicht als protected deklariere, dann können sie nur public sein (um sie vererbbar zu machen) (oder Setter/Getter haben, was aber IMHO unschön ist), was wiederum nicht im anfänglichen Sinne war. Also ist protected die Lösung. Oder bin ich etwa wieder doof 😕

    Das Problem ist nicht wie man die Member "vererbbar macht", sondern dass du sie überhaupt "vererbbar machen" willst...

    Bitte!? Ist das jetzt unüblich geworden, VERERBUNG zu benutzen?

    Nein, wieso!?
    Aber normalerweise setzt man Vererbung zur Modellierung von abstrakten Konzepten ein und nicht um Daten zu vererben...zumindest heutzutage...zumindest in der OOP wie ich sie verstehe...



  • Also, ich vererbe fast immer auch Eigenschaften mit.



  • SeppJ schrieb:

    Hacker schrieb:

    Bitte? Das macht man (zumindest ich) ziemlich oft, das ist doch die einzige Möglichkeit, Daten nach außen zu kapseln und trotzdem vererbbar zu machen!

    Weil du etwas ziemlich oft machst, ist das weder üblich noch guter Stil. Siehe zur Erklärung die Beiträge über deinem.

    🙄



  • Hacker schrieb:

    Also, ich vererbe fast immer auch Eigenschaften mit.

    😕 Es ist doch gar nicht möglich, etwas nicht zu vereben. Jedes Objekt der Subklasse besitzt immerhin ein Objekt der Basisklasse. Nur weil auf etwas nicht zugegriffen werden kann, heißt das nicht, dass es nicht vererbt wurde.



  • Hacker schrieb:

    Wenn ich sie nicht als protected deklariere, dann können sie nur public sein (um sie vererbbar zu machen) (oder Setter/Getter haben, was aber IMHO unschön ist), was wiederum nicht im anfänglichen Sinne war. Also ist protected die Lösung. Oder bin ich etwa wieder doof 😕

    Es wird immer alles vererbt.

    Aber: alles was protected vererbt wird, hebt die Kapselung auf. idR wollen wir, dass gewisse Invarianten eingehalten werden. Wenn du nun protected Member hast, kann jede Kindklasse diese ändern ohne invarianten beachten zu müssen. Das ist schlecht.

    Eigentlich gibt es keinen Grund protected variablen zu haben. Und ich habe das noch nirgendwo sinnvoll eingesetzt gesehen geschweige denn selber mal gebraucht...

    PS: zeig mal ein kleines Beispiel her wo du protected variablen hast.



  • Gugelmoser schrieb:

    Hacker schrieb:

    Also, ich vererbe fast immer auch Eigenschaften mit.

    😕 Es ist doch gar nicht möglich, etwas nicht zu vereben. Jedes Objekt der Subklasse besitzt immerhin ein Objekt der Basisklasse. Nur weil auf etwas nicht zugegriffen werden kann, heißt das nicht, dass es nicht vererbt wurde.

    Das ist mir klar! Ich meine, ich mache sie protected, sodass ich auf sie zugreifen kann.


  • Mod

    Hacker schrieb:

    Das ist mir klar! Ich meine, ich mache sie protected, sodass ich auf sie zugreifen kann.

    Würdest du deine Kinder mit deinem Portemonnaie oder deinem Penis rumspielen lassen? Wenn sie was von dir wollen, sollen sie gefälligst fragen!



  • Gugelmoser schrieb:

    1. In einem anderen Thread wurde letztens gesagt, dass man Member so gut wie nie protected macht. Wieso nicht? Was ist böse daran?

    Da wollte ich dir heute noch antworten. Sorry, dass das so lange gedauert hat.

    Zuerst mal zum Unterschied von öffentlichen und privaten Membern: Es gibt Fanatiker, die behaupten, dass alle Member privat sein sollen und dass man wenn nötig öffentliche Getter und Setter bereitstellen soll. Bei vielen Membern macht das auch aus bekannten Gründen Sinn: Man verrät nichts über Implementierungsdetails, macht externen Code nicht von der Implementierung abhängig, Client-Code kann keine bösen Sachen mit meinen privaten Membern anfangen, ich kann den Datentyp ändern etc.

    Allerdings gibt es auch Member, auf die ich von außen uneingeschränkten Zugriff gewähren will. Klassisches Beispiel wäre std::pair. Wichtig bei öffentlichen Membern ist aber, dass sie sich nie bzgl. Datentyp, Bedeutung etc. ändern werden und ich nichts dagegen habe, dass Client-Code Dinge mit den Membern macht, an die ich ursprünglich nicht gedacht habe. Insbesondere darf es nicht möglich sein, dass ich durch externe Zugriffe auf meine öffentlichen Member in einen inkonsistenten Zustand gerate. Wenn ich also öffentliche Member habe, gebe ich Client-Code die Garantie, dass er mit den Membern machen kann, was er will, und dass sich dieser Teil meiner Implementierung nicht ändert.

    Was ist nun mit geschützten Membern? Für erbende Klassen verhalten sie sich wie öffentliche Member. Insbesondere können andere Programmierer (oder ich in einem Jahr, läuft aufs selbe hinaus) beliebig von meiner Klasse ableiten, sodass ich keine Kontrolle über die erbenden Member habe und Code, der auf meine geschützten Member zugreift, übers gesamte Projekt verstreut sein kann. Also muss ich den erbenden Klassen dieselben Garantien wie bei öffentlichen Membern geben. Für alle anderen sind geschützte Member wie private Member mit all ihren Nachteilen.

    Also vereinen geschützte Member die Nachteile öffentlicher und privater Member. Einerseits will ich die Member nicht privat haben (aus welchen Gründen auch immer, sonst bräuchte ich protected gar nicht), aber ich muss trotzdem Garantien geben wie bei öffentlichen Membern.

    Edit: Wenn du Member hast, für die du keine weitreichenden Garantien geben willst und auf die trotzdem nur die abgeleiteten Klassen Zugriff haben sollen, kannst du die Member privat und Getter und Setter protected machen.



  • Michael E. schrieb:

    Gugelmoser schrieb:

    1. In einem anderen Thread wurde letztens gesagt, dass man Member so gut wie nie protected macht. Wieso nicht? Was ist böse daran?

    Da wollte ich dir heute noch antworten. Sorry, dass das so lange gedauert hat.

    Kein Ding 😉

    Danke für eure Beiträge, insbesondere

    icarus2 schrieb:

    [...] and protected inheritance is something whose meaning eludes me to this day". Will heissen, dass er bis heute nicht herausgefunden hat, wofuer man protected Vererbung brauchen kann. Daher wird man es wohl auch kaum brauchen.

    und

    Michael E. schrieb:

    Was ist nun mit geschützten Membern? Für erbende Klassen verhalten sie sich wie öffentliche Member. Insbesondere können andere Programmierer (oder ich in einem Jahr, läuft aufs selbe hinaus) beliebig von meiner Klasse ableiten, sodass ich keine Kontrolle über die erbenden Member habe [...]

    dot schrieb:

    Meiner Meinung nach bedeutet Vererbung immer "is a". public, protected oder private bestimmen nur wer von dieser "is a" Beziehung weiß.

    Da bin ich anderer Meinung. Ich begründe mal kurz, wieso ich anderer Meinung bin:

    class Foo
    {
    	private:
    		int price;
    
    	public:
    		int getPrice() const { return price; }
    };
    
    class Bar : private Foo {};
    
    int main()
    {
    	Foo f;
    	f.getPrice();
    
    	Bar b;
    	b.getPrice(); // Error: 'int Foo::getPrice() const' is inaccessible.
    }
    

    Ich nehme "is-a" wörtlich. Und wenn ich mit Bar nicht genau dasselbe machen kann wie mit Foo, ist es kein "is-a" mehr.



  • Gugelmoser schrieb:

    dot schrieb:

    Meiner Meinung nach bedeutet Vererbung immer "is a". public, protected oder private bestimmen nur wer von dieser "is a" Beziehung weiß.

    Da bin ich anderer Meinung. Ich begründe mal kurz, wieso ich anderer Meinung bin:

    class Foo
    {
    	private:
    		int price;
    		
    	public:
    		int getPrice() const { return price; }
    };
    
    class Bar : private Foo {};
    
    int main()
    {
    	Foo f;
    	f.getPrice();
    	
    	Bar b;
    	b.getPrice(); // Error: 'int Foo::getPrice() const' is inaccessible.
    }
    

    Ich nehme "is-a" wörtlich. Und wenn ich mit Bar nicht genau dasselbe machen kann wie mit Foo, ist es kein "is-a" mehr.

    Da halt ich dagegen:

    class Foo
    {
    	private:
    		int price;
    
    	public:
    		int getPrice() const { return price; }
    };
    
    class Bar : private Foo
    {
    public:
      Foo& getFoo() { return *this; }
    };
    
    int main()
    {
    	Foo f;
    	f.getPrice();
    
    	Bar b;
    	b.getFoo().getPrice();
    }
    

    Wie gesagt, Bar ist ein Foo, nur weiß das eben niemand außer Bar 😉



  • Hm.. ich bin hier neue aber sind die beide Beispiele eh nicht wirklich relevant?
    Wenn ich eine Klasse „private“ vererbe, dann will ich doch ausdrücklich die externe Nutzung dieser über meine neue Klasse verbieten oder ich erbe halt public?
    Und schon gar nicht möchte ich ( in der Theorie ) eine Methode haben die dann meine private Vererbung wieder sichtbar macht? Ich verliere ja damit die Kontrolle??!!

    😕



  • Es geht nicht darum, dass niemand weiß, dass Foo und Bar etwas gemeinsam haben. Bei normaler Komposition ist das ja auch okay, wenn man für den Member einen getter schreibt. private Vererbung ist nichts anderes als Komposition, nur dass du dir weiterreichende Zugriffsrechte auf einen Member besorgst: eben auf alle protected methoden/member.



  • otze schrieb:

    Es geht nicht darum, dass niemand weiß, dass Foo und Bar etwas gemeinsam haben. Bei normaler Komposition ist das ja auch okay, wenn man für den Member einen getter schreibt. private Vererbung ist nichts anderes als Komposition, nur dass du dir weiterreichende Zugriffsrechte auf einen Member besorgst: eben auf alle protected methoden/member.

    Wieso kann ich dann bei Komposition Bar nicht in ein Foo wandeln? Richtig, weil Bar dann kein Foo mehr ist, sondern ein Foo hat. Dass von außen beides gleich ausschaut, bedeutet doch noch lange nicht, dass es auch ganz genau das gleiche ist!?



  • dot: Wenn du eine solche Konvertierungsmethode bereitstellst, was versprichst du dir dann von privater Vererbung?



  • Darum geht's doch nicht. Es geht um die Tatsache, dass Bar aus Sicht von Bar eben ein Foo ist und nicht nur ein Foo hat. Eben genau was ich zuvor gesagt hab. Wäre dem nicht so, dann könnte ich in dieser Konvertierungsmethode nicht einfach *this returnen. Und genau das wollte ich damit zeigen.



  • otze schrieb:

    private Vererbung ist nichts anderes als Komposition

    Da bin ich auch anderer Meinung. Für mich stellt private-Vererbung in keiner Weise eine Beziehung dar. private-Vererbung bedeutet für mich, dass ich eine bestimmte Funktionalität von irgendetwas übernehmen will, wie z.B. die Funktionalität, dass meine Objekte nicht kopierbar sein sollen:

    class Foo : noncopyable
    

    Michael E. schrieb:

    dot: Wenn du eine solche Konvertierungsmethode bereitstellst, was versprichst du dir dann von privater Vererbung?

    Damit wollte er uns sagen, dass Bar aus ihrer Sicht eben doch ein Foo ist.



  • -.-'


Anmelden zum Antworten