[Erledigt] Finde den Fehler nicht



  • Hallo Leute,

    ich finde den Fehler nicht im Code.
    Warum hat Zeile 38 keine Auswirkung auf den Code? Gültigkeitsbereich?
    Was müsste geändert werden?

    #include <vector>
    #include <iostream>
    
    class B{
    
    private:
    	std::vector<double> elements;
    public:
    	static const int maxdim =3;
    	B(){ elements.insert(elements.begin(),maxdim,0.0); }
    	double get_dim(int dim) {return elements[dim];}
    	void set_dim(int dim,double val) {elements[dim] = val;}
    };
    
    class A{
    	private:
    		std::vector<B> sys;
    	public:
    		static const int maxsys=3;
    
    		A(){
    			B tmpb;
    			sys.insert(sys.begin(),maxsys,tmpb);
    		}
    
    		B get_sys(int pos) const { return sys[pos];}
    		void set_sys(B val) { sys.push_back(val);}
    };
    
    int main(void){
    
    	A classa;
    
    	for(int i=0;i<A::maxsys;i++){
    		for(int j=0;j<B::maxdim;j++){
    				classa.get_sys(i).set_dim(j,1.0);
    		}
    	}
    
    	for(int i=0;i<A::maxsys;i++){
    		std::cout << "sys=" << i << '\n';
    		for(int j=0;j<B::maxdim;j++){
    			std::cout << "dim-" << j << "=" << classa.get_sys(i).get_dim(j) << '\t';
    		}
    		std::cout << '\n';
    	}
    }
    


  • Weil da von get_sys eine Kopie zurückgegeben wird und du auf diese (temporäre) Kopie eine Änderung machst, welche natürlich keine Auswirkung auf das ursprüngliche Objekt hat.

    Zur Lösung des Problems:
    Technisch: Gib eine Referenz oder einen Zeiger zurück.
    Besser: Ändere das Design. Das verletzt das Konzept der Kapselung.



  • drakon schrieb:

    Besser: Ändere das Design. Das verletzt das Konzept der Kapselung.

    Wieso? std::string, std::vector,... machen das doch auch so. Sie haben den []-operator überladen und geben eine referenz auf das n-te Element zurück.



  • drakon schrieb:

    Zur Lösung des Problems:
    Technisch: Gib eine Referenz oder einen Zeiger zurück.

    So? Klappt irgendwie nicht.

    double &set_dim(int dim,double val) {return elements[dim];}
    B &set_sys(int pos) {  return sys[pos];}
    // Zugriff
    classa.set_sys(i).set_dim(j,1.0);
    

    drakon schrieb:

    Besser: Ändere das Design. Das verletzt das Konzept der Kapselung.

    In wie fern?



  • Habe jetzt Referenzen hinzugefügt, klappt leider immer noch nicht

    #include <vector>
    #include <iostream>
    
    class B{
    
    private:
    	std::vector<double> elements;
    public:
    	B(){ elements.insert(elements.begin(),3,0.0); }
    	const double &get_dim(int dim) const {return elements[dim];}
    	double &set_dim(int dim,double val) {return elements[dim];}
    };
    
    class A{
    
    private:
    	std::vector<B> sys;
    public:
    	A(){
    		B tmpb;
    		sys.insert(sys.begin(),3,tmpb);
    	}
    
    	const B &get_sys(int pos) const { return sys[pos];}
    	B &set_sys(int pos) {  return sys[pos];}
    };
    
    int main(void){
    
    	A classa;
    
    	for(int i=0;i<3;i++){
    		for(int j=0;j<3;j++){
    			classa.set_sys(i).set_dim(j,1.0);
    		}
    	}
    
    	for(int i=0;i<3;i++){
    		std::cout << "sys=" << i << '\n';
    		for(int j=0;j<3;j++){
    			std::cout << "dim-" << j << "=" << classa.get_sys(i).get_dim(j) << '\t';
    		}
    		std::cout << '\n' << '\n';
    	}
    	std::cout << '\n';
    }
    


  • Klappt irgendwie nicht.

    Tolle Fehlerbeschreibung. 🙂



  • virtual diva schrieb:

    drakon schrieb:

    Besser: Ändere das Design. Das verletzt das Konzept der Kapselung.

    Wieso? std::string, std::vector,... machen das doch auch so. Sie haben den []-operator überladen und geben eine referenz auf das n-te Element zurück.

    Das ist korrekt, aber das sind eher Sonderfälle, weil man da wirklich Zugriff auf die inneren Elemente braucht. Üblicherweise sollte man so etwas allerdings nicht machen.

    @darkfate
    Was sollen denn die Funktionen deiner meinung nach machen, wenn du eh nur Referenzen auf Objekte zurückgibst?



  • knivil schrieb:

    Klappt irgendwie nicht.

    Tolle Fehlerbeschreibung. 🙂

    Bezieht sich auf weiter oben, das es keine Auswirkung hat.



  • drakon schrieb:

    Was sollen denn die Funktionen deiner meinung nach machen, wenn du eh nur Referenzen auf Objekte zurückgibst?

    Es ist hier stark vereinfacht. Wollte das Grundproblem aufzeigen.
    Jetzt gebe ich Referenzen zurück und habe immer noch 0.0 in allen Elementen.



  • Mach ein kurzes, klares Beipspiel, wo der Fehler deiner Meinung nach passiert und beschreib genau, was du für falsch hälst.

    Vielleicht hast du mich einfach falsch verstanden, aber die Setter da oben (im letzten Code) sind schlichtweg unsinnig.



  • drakon schrieb:

    Zur Lösung des Problems:
    Technisch: Gib eine Referenz oder einen Zeiger zurück.

    An welche Stelle soll da die Referenz hin?



  • Hat sich erledigt... mussten lediglich zwei Zeilen geändert werden.
    Könntest du mir jetzt bitte erklären warum die getter uns setter da unsinning sein sollten?



  • Weil Sie etwas suggerieren, was sie nicht machen!



  • darkfate schrieb:

    Könntest du mir jetzt bitte erklären warum die getter uns setter da unsinning sein sollten?

    Die getter sind nicht das Problem. Und ein setter setzt normalerweise was, oder? Dein setter ist aber nur ein non-const-ref-getter...



  • l'abra d'or schrieb:

    darkfate schrieb:

    Könntest du mir jetzt bitte erklären warum die getter uns setter da unsinning sein sollten?

    Die getter sind nicht das Problem. Und ein setter setzt normalerweise was, oder? Dein setter ist aber nur ein non-const-ref-getter...

    Wie macht man es besser?

    Ich möchte die Variable nicht public freigeben.



  • darkfate schrieb:

    Wie macht man es besser?

    In dem du etwas setzt? Vor allem in B wäre eine Zuweisung nicht schlecht. Wenn du zwar eine "1.0" übergibst, die aber nirgendwo setzt, brauchst du dich nicht wundern, dass du nicht das bekommst was du gesetzt haben wolltest, aber es dann doch nicht getan hast.



  • l'abra d'or schrieb:

    In dem du etwas setzt? Vor allem in B wäre eine Zuweisung nicht schlecht. Wenn du zwar eine "1.0" übergibst, die aber nirgendwo setzt, brauchst du dich nicht wundern, dass du nicht das bekommst was du gesetzt haben wolltest, aber es dann doch nicht getan hast.

    Ich kann gerade nicht nachvollziehen was du meinst, könnten wir mit Codeschnipseln arbeiten? Hier ist das aktuelle, funktionsfähige, Ergebnis.

    #include <vector>
    #include <iostream>
    
    class B{
    
    private:
    	std::vector<double> elements;
    public:
    	static const int maxdim =3;
    	B(){ elements.insert(elements.begin(),maxdim,0.0); }
    	double get_dim(int dim) {return elements[dim];}
    	void set_dim(int dim,double val) {elements[dim] = val;}
    };
    
    class A{
    private:
    	std::vector<B> sys;
    public:
    	static const int maxsys=3;
    
    	A(){
    		B tmpb;
    		sys.insert(sys.begin(),maxsys,tmpb);
    	}
    
    	B get_sys(int pos) const { return sys[pos];}
    	B &set_sys(int pos) { return sys[pos];}
    	void set_sys(int pos, B val) { sys[pos] = val; }
    };
    
    int main(void){
    
    	A classa;
    
    	for(int i=0;i<A::maxsys;i++){
    		for(int j=0;j<B::maxdim;j++){
    			classa.set_sys(i).set_dim(j,1.0);
    		}
    	}
    
    	for(int i=0;i<A::maxsys;i++){
    		std::cout << "sys=" << i << '\n';
    		for(int j=0;j<B::maxdim;j++){
    			std::cout << "dim-" << j << "=" << classa.get_sys(i).get_dim(j) << '\t';
    		}
    		std::cout << '\n';
    	}
    }
    


  • Du hattest vorhin zwischendrin keinen setter, sondern einen weiteren getter implementiert. Warum sollte ein setter überhaupt etwas zurückgeben?

    Schau deinen Code einfach nochmal genau an (den zweiten den du gepostet hast).



  • drakon schrieb:

    Du hattest vorhin zwischendrin keinen setter, sondern einen weiteren getter implementiert. Warum sollte ein setter überhaupt etwas zurückgeben?

    Schau deinen Code einfach nochmal genau an (den zweiten den du gepostet hast).

    Ich weiß gerade nicht wie man es besser/einfacher implementieren könnte.
    Bin für jeden Tipp dankbar. Am besten mit einem Stück Code weil ich mir aus den Sätzen sehr schwer tue Code zusammenzubauen.



  • darkfate schrieb:

    drakon schrieb:

    Du hattest vorhin zwischendrin keinen setter, sondern einen weiteren getter implementiert. Warum sollte ein setter überhaupt etwas zurückgeben?

    Schau deinen Code einfach nochmal genau an (den zweiten den du gepostet hast).

    Ich weiß gerade nicht wie man es besser/einfacher implementieren könnte.
    Bin für jeden Tipp dankbar. Am besten mit einem Stück Code weil ich mir aus den Sätzen sehr schwer tue Code zusammenzubauen.

    Man merkt, dass du ein wenig auf der Leitung stehst.. 😉

    Du hast es ja bereits richtig gemacht..
    Schau nochmal gaaanz genau Zeile 12 im letzten geposteten Code an und vergleich das, was du auf da im zweitletzen geposteten Code hattest.


Anmelden zum Antworten