Friend Class und Vererbung



  • Hi

    Habe folgendes Problem

    Eine Klasse hat einen Protected Member auf den ich zugreifen muss aus einer anderen Klasse. Und zwar sind das alle bgeleiteten Klassen einer abstrakten Basisklasse.

    Ich müsste nun in der einen Klasse friend class für jede einzelne abgeleitete Klasse definieren. Wenn ich nur die Basis Klasse als friend definiere, geht das nicht, oder?
    Kann man die "friend"s nicht vererben?

    danke im voraus

    ps und ich werd mich auch bemühn nicht mehr falsche antworten zu geben



  • Vererben von friends geht nicht.



  • Hallo,

    1310-Logik schrieb:

    Eine Klasse hat einen Protected Member auf den ich zugreifen muss aus einer anderen Klasse. Und zwar sind das alle bgeleiteten Klassen einer abstrakten Basisklasse.

    Welche Klasse ist abgeleitet von der Abstrakten Basisklasse? Die mit dem protected-Member oder die, die darauf zugreifen sollen?
    Ich gehe mal von letzterem aus:

    Ich müsste nun in der einen Klasse friend class für jede einzelne abgeleitete Klasse definieren. Wenn ich nur die Basis Klasse als friend definiere, geht das nicht, oder?

    Nein.

    Kann man die "friend"s nicht vererben?

    Nein. Das Prinzip der Datenkapselung könnte so zu einfach unterlaufen werden.

    edit: langsaaaaaam.

    Gruß, Caipi



  • Jo danke, dann mach ich halt ne Liste von Friends.
    Das Prinzip der Erweiterbarkeit wird dabei aber auch unterlaufen.
    Schade.



  • Hallo

    Mach für die Klasse mit dem protected Member doch einen public Getter/Setter, der eine (konstante) Referenz zurückgibt. Dann brauchst du dich nicht mit friend rumschlagen.

    /Edit : also einen Getter/Setter aus der zugreifenden Klasse heraus, der dann von den abgeleiteten Klassen benutzt werden kann.

    bis bald
    akari



  • Zugegeben, ist nicht schön, könnte aber helfen:

    class Base
    {
    public:
    	const int &getData();
    };
    
    class Derived1 : Base
    {
    	friend const int &Base::getData();
    	static const int data = 8;
    };
    
    const int &Base::getData()
    {
    		return Derived1::data;
    }
    
    class Derived2 : Base
    {
    public:
    	void foo()
    	{
    		int bar = getData();
    	}
    };
    


  • übrigens warum verwendest nicht einfach das visitor oder observer pattern



  • Ui, muss ich erst mal nachschlagen 🤡



  • ja was ist das denn?
    ich hab echt noch nicht den schnall im design.
    wie ich meine klassen mach ist wahrscheinlich horror für euch.

    population                
    -----------------         
    cyclce()                  
    -----------------         
    vector<lifeform*>  ---->  lifeform
                              -----------
                              bool is alive
                              -----------
                              life()
                              population*  // <--- Zugehörigkeit zu einem Stamm 
                              -----------
    

    und davon erb ich für verschiedene species.
    eher chaoutisch oder sinnvol?



  • Meinst du so

    struct population
    {
    };
    
    struct lifeform : population
    {
    };
    
    struct concretespeciesnA : lifeform
    {
    };
    
    struct concretespeciesB : lifeform
    {
    };
    

    ?



  • nein so

    class population
    {
        friend class lifeform_... // alle
        virtual cycle() = 0 {};
    protected:
        vector<lifeform*> breed;  // den brauch ich
    }
    
    class lifeform
    {
        virtual life() = 0 {};
    }
    
    class population_rabbit: public population
    {
        virtual cycle() { //iterate through breed and call (*it)->life }
    }
    
    class lifeform_rabbit: public lifeform
    {
        virtual life() { eat(); move(); }
    }
    


  • Sieht eher nach ner UML-Imitation aus:

    struct population
    {
      vector<lifeform*>  members; // assoc: 0..n ---> lifeform
    };
    
    struct lifeform
    {
    protected:
      bool  alive;
      population*  fellows; // assoc: 1 ---> population
    };
    
    struct concreteSpeciesA : lifeform
    {
    };
    
    struct concreteSpeciesB : lifeform
    {
    };
    


  • das problem ist, das die verschiedenen species auch verschiedene cycles in der population haben.
    in der main hab ich dann nen vector<population> und davon (*iterator).cycle darum die abstrakten basisklassen.
    es soll eben ohne grössere umstände ne specie dazugefügt werden.



  • Wozu brauchen die lifeform_* nun Zugriff auf den vector? Was hast du vor?



  • finix schrieb:

    Wozu brauchen die lifeform_* nun Zugriff auf den vector? Was hast du vor?

    Berechtigte Frage:
    Jedes Lebewesen reageirt mit anderen,
    also das Gras braucht Nachbarn (Game of Life)
    der Hase frisst Gras und paart sich
    dwer Fuchs friss Hasen und paart sich etc..
    deshalb braucht eine Lebensform den Zugriff auf die Individuen jeder Population.

    Hatte erst Gras das wächst, und Hasen die hüpfen, nun sollen die aber interagieren. Hase hüpft nur auf grünes Gras und frisst das, Kollision mit anderen Hasen und so weiter..(Feld Wald Wiesen Simulation)

    Ist mein Design falsch?
    [edit]
    Ich bin kein Informatiker (rate mal: Biologe) und DesignPatterns hab ich mir noch nicht angetan, sollte ich wohl..
    [/edit]



  • Kenne dein insgesamtes Design nicht, aber von dem was ich da sehe sollte sich dein Problem recht leicht lösen lassen, denn ein Hase ist eine lifeform und er ist ein Bestandteil der population, also

    struct rabbit : lifeform, population { };
    


  • struct rabbit : lifeform, population { };
    

    Versteh ich jetz nicht ganz 😕 😕



  • Kennst du keine Mehrfachvererbung?

    class AbgeleiteteKlasse
     : // hinter den Doppelpunkt kommen die Basisklasse(n)
      //sichtbarkeitsbereich, kann public, private oder protected sein
      public         //public bedeutet ist ein und alle können auf die Methoden und Attribute der Basisklasse zugreifen
      Basisklasse1,
      private         //private bedeutet hat ein (ist implementiert mit) und nur die abgeleitete Klasse kann auf die Methoden und Attribut der Klasse zugreifen
      Basisklasse2,
      protected        //protected gibts wohl nur der vollständigkeit halber und wirst du wohl nie brauchen, könnte man verwenden um ist implementiert mit auszudrücken und die zweite Eigenschaft auszunützen, denn alle abgeleiteten Klassen von "AbgeleiteteKlasse" können ebenfalls auf die Methoden und Attribute der BasisKlasse2 zugreifen
      Basisklasse2
    {
    };
    

    so das war ne Kurzeinführung 🙂



  • ok sorry. dann hast Du mich falsch verstanden.
    doch ich kenn mehrfachvererbung.
    aber Population und Lifeform sind verschiedene klassenarten. Lifeform ist keine Population, sondern Population besitzt in seinem Vector 10000 Lifeform pointer. (siehe auch mein posting weiter oben)
    diese alle zusammen werden von der Pop. gesteuert, beeinflussen sich aber untereinander. darum der zugriff über die Pop.klasse von einem Lifeform zum anderen.
    hoffe das versteht irgendwer noch.

    mfg
    ein verwirrter bio-logiker

    ps ich brauch ne Pause



  • Dr. Prof schrieb:

    Kenne dein insgesamtes Design nicht, aber von dem was ich da sehe sollte sich dein Problem recht leicht lösen lassen, denn ein Hase ist eine lifeform und er ist ein Bestandteil der population, also

    struct rabbit : lifeform, population { };
    

    Hier ist der springenden Punkt. "Ein Bestandteil" führt nicht zur öffentlichen Vererbung, denn die heißt nach Liskov "ist ein" und "verhält sich wie". Ein Hase ist aber weder eine Population noch verhält er sich wie eine.


Anmelden zum Antworten