Klasse in Klasse



  • class Papa
    {
        public:
            class Kind;
    
        public:
            Papa();
            virtual ~Papa();
    
        protected:
            char*   m_papaname;
    };
    
    class Papa::Kind
    {
       public:
           Kind();
           virtual ~Kind();
    
           const char* MeinPapa() { return Papa::m_papaname; }
    };
    

    obiger Code führt zu einem Fehler?
    Wie mach ich es richtig, ohne m_papaname static zu machen?



  • hmm...
    mir wurde gerade klar, warum es nicht gehen kann!
    Naja... 🙂

    bis dann



  • was du willst, ist vererbung oder layering
    das hast du aber nicht modelliert.



  • Naja, weiß ja nicht was er will, aber der Code versucht das was ich öfter will und was in C++ leider nicht geht, bzw. nur über hässliche Umwege.
    *neidisch-zu-java-guck*



  • Was geht in Java, was in C++ nicht geht?



  • das was esskar da versucht hat.

    class A {
    int x;
    class B { B() { x = 10; } };
    };

    In C++ ist B aber eine eigene Klasse die extra instanziert werden muss, bzw. ein Objekt von A bräuchte um dessen Inhalt zu bearbeiten.



  • DrGreenthumb:
    wie nennt sich so eine Beziehung?

    was passiert bei:

    class Base
    {
    protected:
      int x;
    public:
      class Child
      {
      public:
        void set(int y) { x=y; } //zugriff auf private??
      };
    };
    
    class Derived : public Base::Child
    {
    };
    
    ...
    Derived d;
    d.set(5); //geht das?
    

    /me versteht den Sinn nicht 😞
    erklär mal bitte



  • Folgendes Konstrukt

    class Papa
    {
        public:
            class Kind;
    
        public:
            Papa();
            virtual ~Papa();
    
        protected:
            char*   m_papaname;
    };
    

    ist keine Parent->Child-Beziehung, sondern eine Outer->Inner-Beziehung.

    Wie löst man das in C++?
    Man definiert sich 2 Makros:

    #define BEGIN_INNER_CLASS(classOuter, classInner) \
      class classInner; \
      friend class classInner; \
      class classInner
      { \
      private: \
        classOuter* This() \
        { return (classOuter*)((BYTE*)this - offsetof(classOuter, m_##classInner)); } \
    public:
    
    #define END_INNER_CLASS(classInner) } m_##classInner;
    

    Jetzt sieht obiges Konstrukt so aus:

    class Papa
    {
    public:
      BEGIN_INNER_CLASS( Papa, Kind)
        const char* MeinPapa() { return This()->m_papaname; }
      END_INNER_CLASS( Kind)
    protected:
      char* m_papaname;
    };
    

    Allerdings ist das für eine Papa-Kind-Beziehung nicht zu gebrauchen, weil es eine 1:1 Beziehung darstellt, und keine 1:N-Beziehung, wie es bei Papa-Kind der Fall sein müsste.



  • /me versteht den Sinn nicht
    erklär mal bitte

    Beispielsweise könnte eine Ereignisbehandlung so aussehen:

    class Fenster {
      int x;
      Button b1;
    
      class b1_handler : public ButtonHandler {
        void onClick() {
          ++x;
        }
      }
    
      Fenster() {
        b1.setHandler( new b1_handler() );
      }
    };
    

    Ähnlich haben die das bei Java gemacht.

    [ Dieser Beitrag wurde am 27.03.2003 um 16:42 Uhr von DrGreenthumb editiert. ]



  • Hallo,
    Hab leider keinen passenden Thread zu meiner Frage gefunden. Dieser schien mir noch am passendsten. Also ich hätte gerne folgendes konstrukt, was leider zu einem fehler führt:

    class huhn{
    public:
      ei foo;
    };
    
    class ei{
    public:
      huhn *bar;
    };
    

    Hat jemand eine Idee wie man das elegant lösen kann (und der compiler trotzdem weiss ob das hihn oder das ei zuerst da war?)?



  • forward-declaration



  • Danke, für die Antwort. Komischerweise kompiliert folgender code immer noch nicht (bzw nur wenn ich foo als pointer deklariere)

    class b;
    
    class a{
    public:
      b foo;
    };
    
    class b{
    public:
      a* bar;
    };
    
    int main(){
    
    }
    


  • Problem gelöst, danke.


Anmelden zum Antworten