Klasse in Klasse in anderer Klasse erzeugen - das wäre klasse.



  • Hallo!

    Vorab: Es geht hier eigentlich um eine Template-Klasse und deren Spezialisierung, falls das einen Unterschied macht.

    Ich habe hier quasi soetwas:

    template<typename T>
    class A0
    {
    
        class B{
        ...
        };
    
        B b;
    
    };
    
    template<typename T>
    class A0<...> //ich nenne es mal A1 !
    {
    
        class B{
        ...
        };
    
        B b;
    
        A0::B b; // <- soll das b aus Klasse A0 sein
    
    };
    

    Sehe ich das richtig, dass es garnicht geht, weil z.B. ein A0::B in A0 ohne Probleme auf A0-Member zugreifen kann. Ein A0::B in A1 hat ja kein A0, macht also Probleme.. ?

    Wenn ich B jetzt auslagere, also ganz normal definiere. Wie kann ich dann dafür sorgen, dass man nur innerhalb der Klasse A0, A1 Objekte davon erzeugen kann?
    Denn das war der eigentliche Grund, warum ich es überhaupt in die Klassen gepackt habe..

    LG
    ULong


  • Mod

    Zwei verschiedene Templateinstanzen verhalten sich wie komplett unterschiedliche Klassen. Egal ob eines davon eine Spezialisierung ist oder nicht!

    Entsprechend ist die Antwort, dass du das B aus unterschiedlichen Spezialisierungen genau so benutzen kannst, als wäre es eine Unterklasse einer anderen Klasse. In diesem Fall müsstest du eben angeben, welches A0 du haben möchtest. "A0" ist noch keine Klasse, sondern nur eine Vorlage, erst eine Instanzierung davon ist eine Klasse.



  • ULong schrieb:

    Template-Klasse

    Falschrum.
    Klassen-Template.
    Nicht Template-Klasse.

    Dann erklärt auch, wieso es so ist, wie von SeppJ erklärt.



  • reverse_iterator schrieb:

    Falschrum.
    Klassen-Template.
    Nicht Template-Klasse.

    Dann erklärt auch, wieso es so ist, wie von SeppJ erklärt.

    Gibt es beides???

    SeppJ schrieb:

    Entsprechend ist die Antwort, dass du das B aus unterschiedlichen Spezialisierungen genau so benutzen kannst, als wäre es eine Unterklasse einer anderen Klasse.

    Kann man Unterklassen anderer Klassen denn einfach so instanzieren, also ohne Oberklasse?? Ich dachte, Objekte davon kann man nur in der Oberklasse erzeugen. Und habe halt gehofft, dass man evtl auch Objekte davon in Template-Spezialisierungen erzeugen kann ?! Oder könnte da ein "friend" helfen?
    Allgemein gefragt: Was kann man denn so mit Unterklassen anstellen, bzw. was gerade nicht?! (Kann man typedefs eigentlich auch als Klassen betrachten?)

    Ich habe bei meinem Bsp. wohl etwas zu viel gespart. Hier nochmal eins mit dem Problem das ich hier sehe:

    template<typename T> class C
    {
    	int i;
    
    	class P
    	{
    		int getI(void)
    		{
    			return i;
    		}
    	} p;
    
    };
    
    template<typename T> class C<B<T> > //B: andere Klasse
    //template<typename T> class C<double> //geht das auch?
    {
    	int i; //alternativ garnicht vorhanden..
    
    	//der Compiler meckert hier eh, aber wenn es denn irgendwie geht:
    	C<T>::P pp; // worauf greift pp.getI() nun zu??
    
    };
    

    Wie sähe der Code denn richtig aus??

    LG
    ULong


  • Mod

    Wie gesagt, ist die Fragestellung bezüglich Unterklassen völlig unabhängig von Templates. Unterschiedliche Klassentemplateinstanzierungen sind diesbezüglich (und auch bezüglich jeden anderen Themas) einfach unterschiedliche Klassen:

    template <typename T> class foo{};
    class bar_int{};
    class bar_double{};
    
    // foo<int> hat mit foo<double> so viel zu tun wie bar_int mit bar_double.
    // Einen ähnlichen Namen, sonst nichts.
    

    Was es allgemein mit Unterklassen auf sich hat:
    http://en.cppreference.com/w/cpp/language/nested_types

    Zugriff von außen auf die Unterklassen ist genau so geregelt, wie sonst auch. Sie können public, private oder protected sein. Wohlgemerkt ist eine Klasse kein Objekt! Bloß weil eine Klasse eine Unterklasse hat, haben Objekte dieser Klasse kein Unterobjekt der Unterklasse. Unterklassen sind ganz normale Klassendefinitionen, aber eben im Namensraum der Oberklasse.



  • Zugriff von außen auf die Unterklassen ist genau so geregelt, wie sonst auch. Sie können public, private oder protected sein. Wohlgemerkt ist eine Klasse kein Objekt! Bloß weil eine Klasse eine Unterklasse hat, haben Objekte dieser Klasse kein Unterobjekt der Unterklasse. Unterklassen sind ganz normale Klassendefinitionen, aber eben im Namensraum der Oberklasse.

    Das Klassen keine Objekte sind, habe ich wohl verstanden.. Es geht mir ja gerade um die Erzeugung von Objekten einer Unterklasse in einer anderen Klasse, nicht in der eigentlichen Oberklasse.
    Wie im Beispielcode angemerkt, bereitet es mir Kopfzerbrechen, was passiert, wenn ich aus der Unterklasse auf Member der Oberklasse zugreife, sobald ich Objekte der Unterklasse in einer anderen Klasse erzeuge. Die Memeber sind im schlechtesten Fall ja garnicht vorhanden, so wie ich das sehe. Darum hätte ich jetzt erstmal gesagt, dass es garnicht geht..

    LG
    ULong


  • Mod

    Wenn du den Unterschied zwischen Klasse und Objekt verstanden hast, dann sollte sich doch auch die Frage erledigt haben. Denn wenn du ein Objekt einer Unterklasse erzeugst, dann gehört dazu noch lange kein Objekt der Oberklasse. Entsprechend ist dein Beispielcode auch Unsinn, denn ein P-Objekt kann auf kein i eines C-Objekts zugreifen, weil zu einem P-Objekt kein C-Objekt gehört und umgekehrt. Ganz egal ob an irgendeiner Stelle Templates im Spiel sind oder nicht. Das einzige, was das Template in deinem Beispiel macht, ist, dass die Fehlermeldung erst bei der Benutzung von P auftritt, weil erst dann klar ist, welches i gemeint ist. Wenn du das Template weg ließest, würdest du auch sofort einen Fehler bekommen:

    class C
    {
        int i;
    
        class P
        {
            int getI(void)
            {
                return i;
            }
        } p;
    };
    

    PS: In deinem Fall gehört auch zu jedem C-Objekt ein P-Objekt als Member namens p. Das ist aber nur in deinem Fall so, im Allgemeinen braucht das nicht so zu sein.


Anmelden zum Antworten