Vererbungsfrage



  • Hi,

    ich lerne im Moment C++ und ich bin im Moment an einem Problem, dass ich noch nicht so ganz verstehe:

    Es existieren 2 Klassen, genannt "Base" und "Foo". Base verfügt über einen public Integer-Array (mit 3 Elementen). Es ist völlig egal ob das jetzt ein Array oder ein Vector ist, falls das jemand anmerken will.

    Was ich will:
    Ich will die Werte des Integer-Arrays aus "Base" mit der Klasse "Foo" manipulieren ohne Vererbung. Muss ich hierfür das "Base"-Objekt im Konstruktor von "Foo" der Klasse übergeben? Wenn ja, habe ich irgendwo einen Denkfehler und es funktioniert trotzdem nicht:

    #include <iostream>
    
    class Base {
    public:
    	int values[3];
    	void showValues();
    };
    
    void Base::showValues() {
    	std::cout << "Value 0: " << values[0] << std::endl;
    	std::cout << "Value 1: " << values[1] << std::endl;
    	std::cout << "Value 2: " << values[2] << std::endl;
    }
    
    class Foo {
    private:
    	Base b;
    public:
    	Foo(Base &b);
    	void setValue(int v, int x) {
    		b.values[v] = x;
    	}
    };
    
    Foo::Foo(Base &b) {
    	this->b = b;
    }
    
    int main() {
    	Base B;
    	Foo a(B);
    	a.setValue(0, 910);
    
    	B.showValues();
    
    	system("PAUSE");
    	return 0;
    }
    

    Eigentlich sollte der erste Wert(0) 910 sein - ist er aber nicht. Liegt der Fehler evtl. bei der Übergabe des Objekts? Kopiere ich das Objekt hier nur und Foo arbeitet mit einer "eigenständigen" Version von "Base"?

    Vielen Dank



  • Und Pardon, der Titel passt eigentlich nicht. Es ist eindeutig zu spät...



  • in Zeile 26 erstellst du eine Kopie von B.
    Das B in Foo ist danach ein anderes wie das B in der main.
    Mach Zeile 17 zu Base &b, dann sollte es so gehen, wie du denkst.

    greetz KN4CK3R



  • Okay, hat soweit geklappt, danke. Ich musste nur beim Konstruktor von Foo direkt noch die Initialisierung von b anhängen:

    Foo::Foo(Base &b) : b(b) {
    

    Irgendwie aber sagt mir mein Gefühl, dass das Ganze nicht wirklich schön ist? Oder ist es schön? Ich würde mir ungern unschönes Design angewöhnen...



  • solange irgendwann dokumentiert ist, dass das Objekt B durch Foo verändert wird, ist das schon in Ordnung

    greetz KN4CK3R



  • KN4CK3R schrieb:

    solange irgendwann dokumentiert ist, dass das Objekt B durch Foo verändert wird, ist das schon in Ordnung

    greetz KN4CK3R

    Zur Not zu erkennen am Konstruktor (const correctness)



  • camper sagt, Referenzen als Member-Variablen sind schlechtes Design- und camper ist hier der king.



  • Um das nochmal klar zu stellen: a.b und B sind zwei verschiedene Objekte. Du machst im wesentlichen nichts anderes als

    int x;
    int y;
    y = x;
    x = 910;
    cout << y;
    

    und wunderst dich, dass, wenn du y ausgibst, da nicht garantiert 910 rauskommt.

    Fiedl schrieb:

    Was ich will:
    Ich will die Werte des Integer-Arrays aus "Base" mit der Klasse "Foo" manipulieren ohne Vererbung. Muss ich hierfür das "Base"-Objekt im Konstruktor von "Foo" der Klasse übergeben?

    Das mit der Referenz (wie vorgeschlagen) ist eine Option. Alternativ kannst du in Foo eine Zeigervariable definieren und übergibst dem Konstruktor die Adresse von B, so dass diese im Zeiger gespeichert werden kann:

    ...
    class Foo {
    private:
       Base* zeiger;
    public:
       explicit Foo(Base* p);
    
       void setValue(int v, int x) {
          b->values[v] = x;
       }
    };
    
    Foo::Foo(Base* p)
    :ptr(p)
    {}
    
    int main() {
       Base B;
       Foo a(&B); // Adresse holen und übergeben
       ...
    


  • Sone schrieb:

    camper sagt, Referenzen als Member-Variablen sind schlechtes Design- und camper ist hier der king.

    Irgendwie bin ich mir sicher, dass er das nicht so absolut pauschal gesagt haben wird...



  • pumuckl schrieb:

    Sone schrieb:

    camper sagt, Referenzen als Member-Variablen sind schlechtes Design- und camper ist hier der king.

    Irgendwie bin ich mir sicher, dass er das nicht so absolut pauschal gesagt haben wird...

    Nein hat er nicht, da hast du natürlich Recht. Ich such gleich den Link raus.



  • camper schrieb:

    [...]
    Allerdings sind Referenzen [...] ohnehin in fast allen Klassen deplaziert.

    http://www.c-plusplus.net/forum/p1815796, dritter Post.


  • Mod

    pumuckl schrieb:

    Sone schrieb:

    camper sagt, Referenzen als Member-Variablen sind schlechtes Design- und camper ist hier der king.

    Irgendwie bin ich mir sicher, dass er das nicht so absolut pauschal gesagt haben wird...

    Jedenfalls betrachte ich es nicht als Designfrage.



  • Sone schrieb:

    camper schrieb:

    [...]
    Allerdings sind Referenzen [...] ohnehin in fast allen Klassen deplaziert.

    http://www.c-plusplus.net/forum/p1815796, dritter Post.

    camper schrieb:

    Meine Aussage war auch primär eher an weniger Erfahrene gerichtet

    Später in dem Thread 😉

    Außerdem:

    camper schrieb:

    Proxies: da diese Referenzen imitieren, überrascht hier nicht, dass Referenzen als Member verwendbar sind, da Kopier- und Zuweisungssemantik auseinanderfallen.

    Und in diesem Thread verhält sich Foo ähnlich einem Proxy für das Base-Objekt, das der Ctor übergeben bekommt.

    Hier handelt es sich also um einen der Fälle, die camper in seiner nicht-Design-Aussage explizit nicht gemeint hat 😛


Anmelden zum Antworten