setter Methode ändert den Wert nicht (Vererbung)



  • Hi Leute,

    habe zum Test 2 Klassen geschrieben (Ware und Brot). Brot erbt von Ware.
    Ich initialisiere ein Brot und möchte den Preis mit setPreis(1.00) ändern.
    Das funktioniert leider nicht. Muss ich vllt in C++ geerbte Methoden neu definieren, das wäre viel arbeit alles doppelt zu machen?

    Hier mal die Codes mit kommentaren was sie ausgeben.

    Main

    #include "stdafx.h"
    #include "brot.h"
    
    using namespace std;
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	Brot *w = new Brot("Brot",1.25,20.5);
    	cout << "Name: " << w->getName() << endl; // Gibt Brot aus
    	cout << "Preis: " << w->getPreis() << endl; // Gibt 1.25 aus
    	w->setPreis(1.10); // Hier möchte ich den Preis ändern
    	cout << "Preis: " << w->getPreis() << endl; // Hier der FEHLER (gibt auch 1.25 aus)
    	cout << "Gewicht: " << w->getGewicht() << endl; // gibt 20.5 aus
    	delete w;
    	system("pause");
    	return 0;
    }
    

    Ware.h

    #include <string>
    
    using namespace std;
    
    class Ware {
    private:
    	string name;
    	double preis;
    public:
    	void setName(string);
    	string getName();
    	void setPreis(double);
    	double getPreis();
    	Ware(string, double);
    };
    

    ware.cpp

    #include "stdafx.h"
    #include "ware.h"
    
    using namespace std;
    
    Ware::Ware(string name, double preis){
    	this->name = name;
    	this->preis = preis;
    }
    
    void Ware::setName(string name){
    	this->name = name;
    }
    
    void Ware::setPreis(double Preis){
    	this->preis = preis;
    }
    
    string Ware::getName(){
    	return this->name;
    }
    
    double Ware::getPreis(){
    	return this->preis;
    }
    

    brot.h

    #include <string>
    #include "ware.h"
    
    using namespace std;
    
    class Brot : public Ware {
    private:
    	double gewicht;
    public:
    	Brot(string, double, double);
    	double getGewicht();
    };
    

    brot.cpp

    #include "stdafx.h"
    #include "brot.h"
    
    Brot::Brot(string name, double preis, double gewicht) : Ware(name,preis) {
    	this->gewicht = gewicht;
    }
    
    double Brot::getGewicht() {
    	return this->gewicht;	 
    }
    


  • Ui hab den Fehler auf einmal gefunden.. Preis war groß geschrieben bei den Parametern der Funktion setPreis()



  • Edit: Hast du ja selbst gefunden 🙂

    An die m-Präfix-Bekämpfer: Das kann also passieren! 🤡



  • m-Präfix?



  • Es gab so eine Diskussion um den Sinn von m-Präfixen bei Membervariablen, also z.B. mName und mPreis . Ich will dich aber damit nicht beeinflussen, ist ganz okay wie du es machst 🙂



  • Es ist üblich, Membervariablen in irgendeiner Weise als solche zu kennzeichnen. Eine Konvention ist, ein m_ voranzustellen, also etwa

    class Ware {
    private:
        std::string m_name;  // <-- hier
        double      m_preis;
      ...
    };
    

    Ich persönlich stelle einen Unterstrich ans Ende des Variablennamen. Letztlich ist das dann Geschmackssache; der gewollte Effekt ist halt nur, dass am Namen erkennbar ist, ob eine lokale oder eine Membervariable gemeint ist.

    Btw, du solltest es dir dringend verkneifen, in Headern

    using namespace std;
    

    zu schreiben. Wenn mal jemand anders deinen Code benutzen will, rechnet der nicht damit, dass deine Header ihm den gesamten Namensraum std in den globalen ziehen.



  • seldon schrieb:

    Es ist üblich, Membervariablen in irgendeiner Weise als solche zu kennzeichnen.

    Üblich, aber vielleicht sinnlos, je nach sonstigem Programmierstil.



  • okay das mit dem mPräfix habe ich verstanden. Meiner Meinung nach brauch man das nicht. Da ich durch this-> sehe, dass ich gerade mit der membervariable arbeite.

    wenn ich den namespace nicht angebe bekomme ich einen Fehler. Es ist sehr viel Aufwand und unübersichtlicher das alles expliziet vor die datentypen zu schreiben. Gibt es da noch eine andere gute Lösung und ist es okay wenn ich das in die .cpp Dateien schreibe?

    Genauso verstehe ich nicht warum ich bei den Methoden der Klasse "Ware" immer ein Ware:: vor die Methode setzen muss? Warum nicht einfach ein class Ware { } aussenrum wäre viel weniger arbeit?



  • bruno32 schrieb:

    wenn ich den namespace nicht angebe bekomme ich einen Fehler. Es ist sehr viel Aufwand und unübersichtlicher das alles expliziet vor die datentypen zu schreiben. Gibt es da noch eine andere gute Lösung

    Nein.

    bruno32 schrieb:

    und ist es okay wenn ich das in die .cpp Dateien schreibe?

    Ja, vollkommen ok.

    bruno32 schrieb:

    Genauso verstehe ich nicht warum ich bei den Methoden der Klasse "Ware" immer ein Ware:: vor die Methode setzen muss? Warum nicht einfach ein class Ware { } aussenrum wäre viel weniger arbeit?

    Klassendefinitionen müssen an einem Stück sein.
    Sonst könnte jemand in die Klasse nochwas später hinzufügen und Böse Sachen machen.



  • okay vielen dank



  • bruno32 schrieb:

    wenn ich den namespace nicht angebe bekomme ich einen Fehler. Es ist sehr viel Aufwand und unübersichtlicher das alles expliziet vor die datentypen zu schreiben. Gibt es da noch eine andere gute Lösung und ist es okay wenn ich das in die .cpp Dateien schreibe?

    Ich habe mir mit der Zeit angewöhnt, den Namensraum fast immer anzugeben. Gerade wenn man verschiedene Bibliotheken hat, gibt es mehr als nur std , und teilweise sogar gleiche Bezeichner. Durch Angabe des Namensraums sieht man direkt, woher ein Bezeichner kommt und verhindert eventuelle Namenskonflikte.

    bruno32 schrieb:

    Genauso verstehe ich nicht warum ich bei den Methoden der Klasse "Ware" immer ein Ware:: vor die Methode setzen muss? Warum nicht einfach ein class Ware { } aussenrum wäre viel weniger arbeit?

    Das ist halt die Syntax von Memberfunktionsdefinitionen in C++.

    Im Ernst: Du solltest dir nicht zu viele Gedanken um den Schreibaufwand machen. Du wirst bald sehen, dass es wichtigere Probleme gibt 😉



  • bruno32 schrieb:

    Genauso verstehe ich nicht warum ich bei den Methoden der Klasse "Ware" immer ein Ware:: vor die Methode setzen muss?

    Naja, soll der Compiler raten, zu welcher Klasse deine Methode gehört? :: == Zugehörigkeit angeben.



  • bruno32 schrieb:

    Genauso verstehe ich nicht warum ich bei den Methoden der Klasse "Ware" immer ein Ware:: vor die Methode setzen muss? Warum nicht einfach ein class Ware { } aussenrum wäre viel weniger arbeit?

    Das liegt daran, dass du die Methode ausserhalb der Klasse definierst. Wenn du das innerhalb der Klasse tust (also in der .h) dann brauchst du dem Compiler nicht mehr hinterher sagen: "übrigens das ist jetzt die Implementierung der Methode X von Klasse Y". Ist natürlich bei großen Methoden unübersichtlicher.



  • naja gut. Ich werde mich dran gewöhnen.

    Vielen dank an alle 🙂


Anmelden zum Antworten