Abstrakte Klasse



  • Danke für eure Antworten Leute^^



  • Ähm ja nächste frage^^

    wenn ich z.b das mache:

    class Attribute
    {
        private:
        std::string Value;
        public:
        void setValue() = 0;
    };
    

    Dann ich ja in der Klasse wo die Methode redefeniert wird nicht mehr auf Value zugreifen. Währe es hier nicht sinvoll Value als protected zu dekladieren?

    Mfg Wikinger75!


  • Administrator

    Dein Beispiel ist unsinnig. Wieso sollte setValue abstrakt sein, wenn der Wert, welcher gesetzt wird, in Attribute liegt? Vielleicht suchst du eher sowas?

    class Attribute
    {
    private:
      std::string vm_alue;
    
    protected:
      virtual void on_value_changed() { }
    
    public:
      void set_value(std::string const& value)
      {
        m_value = value;
    
        on_value_changed();
      }
    };
    

    Ich würde aber on_value_changed nicht abstrakt machen. Erscheint mir auch unsinnig.

    Grüssli



  • Wikinger75! Hast du meine Antwort unter 5. nicht gelesen? Du hast mit dem string-Attribut doch gegen den eigentlichen Grund der abstrakten Klasse gehandelt, und wusstest anscheinend doch, was da rein gehört. Also warum hast du die Methode setValue nicht implementiert? Wenn du setValue nicht kennst, kennst du logischerweise auch Value nicht.



  • @Dravere
    Hmm währe so auch gut...

    @Bulli

    Wikinger75! Hast du meine Antwort unter 5. nicht gelesen? Du hast mit dem string-Attribut doch gegen den eigentlichen Grund der abstrakten Klasse gehandelt, und wusstest anscheinend doch, was da rein gehört. Also warum hast du die Methode setValue nicht implementiert? Wenn du setValue nicht kennst, kennst du logischerweise auch Value nicht.

    Ja, aber mit einer Abstracten Klasse gibt man ja eine schablone vor und alle die von dieser Schablone erben sollen ein Value atribut enthalten, wenn ich dieses ja aber nicht in der absrtacten klasse erwähne, werden die anderen Klassen nicht dazu verdonert dieses zu besitzen.
    SetValue abstract zu machen ist unsinig das stimmt, aber es soll kein Objekt von dieser Klasse erzeugt werden können!

    Es gibt hier also zwei möglichkeiten.

    1.) Value wird protected und setValue abtract, damit es überschrieben werden muss und man auf Value noch so zugreifen kann.

    2.) Value wird privat und setValue wird als eine normale methode impementiert, jedoch wie kann ich dan verhindern, dass man davon kein objekt erzeugen kann?

    Obwohl mir wird auch grade Klar das es unötig ist die klasse als abstract zu machen, da es sinvoll währe, das ich einen Zeiger von der Basisklasse machen kann und so auf die anderen Objekte der vererbten Klassen zugreifen kann.

    Mfg Wikinger75!


  • Administrator

    class VonMirKannManKeinObjekteHerstellen
    {
    protected:
      VonMirKannManKeinObjekteHerstellen()
      {
      }
    };
    

    Mach den Konstruktor protected. So können davon abgeiltete Klassen erstellt werden, aber man kann die Basis selber nicht kontruieren. Für sowas braucht man keine abstrakte Klasse.

    Grüssli



  • Wikinger75 schrieb:

    jedoch wie kann ich dan verhindern, dass man davon kein objekt erzeugen kann?

    Destructor pure virtual machen. Allerdings musst du trotzdem noch eine Implementierung des Dtor bereitstellen weil der dann von den Dtoren der abgeleiteten Klassen aufgerufen wird.
    In einigen Codingstyles wird vorgeschlagen/verlangt, dass bei abstrakten Klassen grundsätzlich auch der Dtor pur virtuell gekennzeichnet wird - aus verschiedenen Gründen.





  • pumuckl schrieb:

    Destructor pure virtual machen. Allerdings musst du trotzdem noch eine Implementierung des Dtor bereitstellen weil der dann von den Dtoren der abgeleiteten Klassen aufgerufen wird.

    Ist das nicht ein wenig widersprüchlich? Rein virtuell sollte meines Erachtens eine Funktion gemacht werden, die erst in abgeleiteten Klassen implementiert wird.

    Was spricht denn gegen einen protected -Konstruktor?



  • Nexus schrieb:

    Ist das nicht ein wenig widersprüchlich? Rein virtuell sollte meines Erachtens eine Funktion gemacht werden, die erst in abgeleiteten Klassen implementiert wird.

    Rein virtuell heißt nicht dass man nicht ne default-Implementierung zur Verfügung stellen kann. Es heißt nur dass sie in abgeleiteten Klassen explizit implementiert werden muss. Und das macht beim Dtor im Zweifel ja der Compiler für uns.

    Was spricht denn gegen einen protected -Konstruktor?

    Folgendes:

    class Base //sollte abstrakt sein
    {
    protected:
      Base() {}
    };
    
    class Derived : public Base
    {
    private: //Instanzbildung verhindern
      Derived();
      Derived(Derived const&);
      ~Derived();
    public:
      static Base* makeBase() 
      {
        cout << "Und die Moral von er Geschicht:\nProtected Ctor macht die Klasse abstract nicht." << endl;
        return new Base;
      } 
    };
    


  • pumuckl schrieb:

    In einigen Codingstyles wird vorgeschlagen/verlangt, dass bei abstrakten Klassen grundsätzlich auch der Dtor pur virtuell gekennzeichnet wird - aus verschiedenen Gründen.

    "Grundsätzlich" ist spätestens mit COM relativiert.

    Nexus schrieb:

    Ist das nicht ein wenig widersprüchlich? Rein virtuell sollte meines Erachtens eine Funktion gemacht werden, die erst in abgeleiteten Klassen implementiert wird.

    Wenn man eine Klasse mit einem abstract -Keyword entsprechend attribuieren könnte, dann wäre der Kunstgriff der rein virtuellen Funktionen mit Default-Implementierung nicht notwendig gewesen. Aber dafür hätte man ja ein zusätzliches Schlüsselwort gebraucht :p



  • pumuckl schrieb:

    Rein virtuell heißt nicht dass man nicht ne default-Implementierung zur Verfügung stellen kann. Es heißt nur dass sie in abgeleiteten Klassen explizit implementiert werden muss. Und das macht beim Dtor im Zweifel ja der Compiler für uns.

    Ja, das schon. Aber abgesehen vom Destruktor ist das sowieso irrelevant, da bei abgeleiteten Klassen nicht automatisch die Basisklassenversion der Funktion aufgerufen wird.

    pumuckl schrieb:

    Und die Moral von er Geschicht: Protected Ctor macht die Klasse abstract nicht

    Aber es ging doch darum, die Instanziierung von aussen zu verhindern? Dass diese innerhalb abgeleiteter Klassen möglich ist, tut ja nichts zur Sache...

    audacia schrieb:

    Aber dafür hätte man ja ein zusätzliches Schlüsselwort gebraucht :p

    Du spielst wohl auf das Recycling an? 😉

    Ich sehe die Idee hinter dem "Hack" nicht ganz. Warum soll eine Klasse abstrakt sein, nur damit sie selber nicht instanziierbar ist, aber abgeleitete Klassen es automatisch sind? Meistens braucht man rein virtuelle Funktionen im Zusammenhang mit einer Funktionalität, die die Basisklasse aufgrund mangelnder Spezialisierung noch nicht hat.



  • Nexus schrieb:

    pumuckl schrieb:

    Und die Moral von er Geschicht: Protected Ctor macht die Klasse abstract nicht

    Aber es ging doch darum, die Instanziierung von aussen zu verhindern? Dass diese innerhalb abgeleiteter Klassen möglich ist, tut ja nichts zur Sache...

    Nur als Bestandteil abgeleiteter Klassen, ja. Abstrakt heißt es darf keine alleinstehenden Objekte der Klasse geben. Genau das ist in meinem Beispiel oben aber möglich - mit pur virtuellen Methoden aber nicht.



  • Wikinger75 schrieb:

    Ja, aber mit einer Abstracten Klasse gibt man ja eine schablone vor und alle die von dieser Schablone erben sollen ein Value atribut enthalten, wenn ich dieses ja aber nicht in der absrtacten klasse erwähne, werden die anderen Klassen nicht dazu verdonert dieses zu besitzen.
    SetValue abstract zu machen ist unsinig das stimmt, aber es soll kein Objekt von dieser Klasse erzeugt werden können!

    Nein, du hast es leider nicht verstanden. Woher willst du wissen, das der Implementierer der Schnittstelle ein Value-Attribut braucht??? Du weißt es nicht! Du kannst eine Default-Implementierung anbieten, aber dann ist es nicht mehr abstrakt, sondern deine Methode nur virtuell (nicht pur virtual).

    Mit abstrakten KLassen gibts du die Schnittstelle vor, Punkt!

    Denn was ist, wenn der Implementierer keinen Value haben will, sondern den Wert z.B. von einem Server holt?

    class Base
    {
        public:
           virtual void setValue(int) = 0;
           virtual int getValue() = 0;
    };
    
    class Special : public Base
    {
        Server server;
        public:
          void setValue(int a)
          {
                server.set(a);
          }
    
          int getValue()
          {
                return server.get();
          }
    };
    

    In dem obigen Beispiel wäre dein Value-Attribut arbeitslos und das fünfte Rad am Wagen. Niemand nutzt es, es verbraucht Speicherplatz und wird andere Benutzer die den Source warten sollen, verwirren.

    Wenn du es besser weißt, als der Implementierer, dann mach es nicht pur virtual! Sondern nur virtual.



  • pumuckl schrieb:

    Nur als Bestandteil abgeleiteter Klassen, ja. Abstrakt heißt es darf keine alleinstehenden Objekte der Klasse geben. Genau das ist in meinem Beispiel oben aber möglich - mit pur virtuellen Methoden aber nicht.

    Hmm, das stimmt natürlich. Aber ich dachte, es ginge Wikinger75 bei seiner Frage grundsätzlich darum, die Instanziierung eines Objekts von aussen zu verbieten.

    Wie gesagt kommt mir das Vorgehen aber von Grund auf eher merkwürdig vor, da ich eigentlich immer den Fall hatte, in dem eine Basisklasse nicht instanziiert werden sollte, weil sie noch kein konkretes Objekt repräsentiert. Wenn alle Funktionen bereits fest stehen, ist das Objekt für mich konkret. Ein künstliches Abstrakt-Machen durch einen rein virtuellen, aber doch implementierten Destruktor scheint mir der falsche Ansatz zu sein...



  • pumuckl schrieb:

    ..."Und die Moral von er Geschicht:\nProtected Ctor macht die Klasse abstract nicht."...

    😃 😃 😃 😃 🤡 👍

    Das werde ich so schnell nicht vergessen => Didaktik 1,0

    Gruß,

    Simon2.


Anmelden zum Antworten