Klasse und Frage zum Konstruktor



  • vip@r schrieb:

    Diese Klasse soll (irgend)eine Berechnung durchführen. Dient ja nur zur Veranschaulichung...

    Hi,

    aber da liegt schon das Problem. Deine Klasse ist nicht so wirklich eine Klasse, bzw. sollte keine sein.
    Deshalb hast du wohl auch Probleme.
    Wenn du dir ein Standard-Klassenbeispiel nimmst, wie z.B. "Fahrzeug" oder sowas,
    dann hat die Klasse auch sinnvolle Attribute und diese lassen sich im Konstruktor sinnvoll setzen.



  • Ich lese ein Buch parallel zu den Folien nämlich "Jetzt lerne ich C++" von Markt und Technik.

    Gut, ich überleg mir mal eine neue Klasse. Etwas anschaulicheres. Ich poste dann meinen neuen Code.



  • Ah, C++ in 21 Stunden.
    Interessantes Vorhaben, die Folien aus einem Buch verstehen zu wollen mit dem Text des bekanntlich schlechtesten Buchs. Und wenns nicht klappt, schaust Du in kein gutes Buch, sondern fragst hier. Ich finde nicht, daß wir nur Buchersatz für Dich sein sollten. Die paar Euro mußt Du schon raushauen. Oder mehrere Tutorials durcharbeiten. Oder einen Studenten aus der Nachbarschaft für die ersten 50 oder 100 Stunden C++-Nachhilfe bezahlen.
    Wenn ich genervt werde und es nach allzu wenig Eigenleistung oder Selbstblockade aussieht, schließe ich Deine Fragen einfach.



  • So Leute!

    C++ in 21 Stunden.

    Nein! Eben nicht C++ in 21 stunden, sondern "Jetzt lerne ich C++".

    Hier dann nochmal vielleicht ein etwas anschaulicheres Beispiel:

    #include<iostream>
    using namespace std;
    
    class Automobil
    {
    private:
    	int wert1, wert2, wert3, wert4;
    
    public:
    	void raeder(int wert)
    	{
    		if(wert == 1)
    		{
    			cout << "Auto hat jetzt Raeder!" << endl;
    		}
    		else
    		{
    			cout << "Auto hat keine Raeder!" << endl;
    		}
    	}
    
    	void motor(int wert)
    	{
    		if(wert == 1)
    		{
    			cout << "Auto hat jetzt Motor!" << endl;
    		}
    		else
    		{
    			cout << "Auto hat keine Motor!" << endl;
    		}
    	}
    
    	void lichter(int wert)
    	{
    		if(wert == 1)
    		{
    			cout << "Auto hat jetzt Lichter!" << endl;
    		}
    		else
    		{
    			cout << "Auto hat keine Lichter!" << endl;
    		}
    	}
    
    	void fahrer(int wert)
    	{
    		if(wert == 1)
    		{
    			cout << "Auto hat jetzt einen Fahrer!" << endl;
    		}
    		else
    		{
    			cout << "Auto hat keinen Fahrer!" << endl;
    		}
    	}
    };
    
    int main()
    {
    	int wert = 1;
    	Automobil zusammenbauen;
    
    	zusammenbauen.raeder(wert);
    	zusammenbauen.motor(wert);
    	zusammenbauen.lichter(wert);
    	zusammenbauen.fahrer(wert);
    
    return 0;
    }
    


  • Das ist genauso Quark.
    Und zusammenbauen ist doch nur eine Tätigkeit.



  • vip@r schrieb:

    Hier dann nochmal vielleicht ein etwas anschaulicheres Beispiel:

    und ein ziemlich grausames dazu. Ich kommentier mal, was daran alles sehr unschön bis grausam ist:

    #include<iostream>
    using namespace std;
    
    class Automobil
    {
    private:
    	int wert1, wert2, wert3, wert4; 
       //1) warum alles ints?
       //2) wert1, wert2 usw. sind nicht sehr sinnvolle bezeichner, 
       //da weiß irgendwann niemand (auch du nicht), was die variablen sollen
    
    public:
    	void raeder(int wert)  
            //was soll wert sein? und wass soll die funktion machen?
            //der Funktionsrumpf sieht eher danach aus, als ob das Argument eher
            // ein bool sein sollte.
    	{
    		if(wert == 1)
    		{
    			cout << "Auto hat jetzt Raeder!" << endl;
    		}
    		else
    		{
    			cout << "Auto hat keine Raeder!" << endl;
    		}
    	}
    
    	void motor(int wert)
            //siehe oben
    	{
    		if(wert == 1)
    		{
    			cout << "Auto hat jetzt Motor!" << endl;
    		}
    		else
    		{
    			cout << "Auto hat keine Motor!" << endl;
    		}
    	}
    
    	void lichter(int wert)
            //siehe oben
    	{
    		if(wert == 1)
    		{
    			cout << "Auto hat jetzt Lichter!" << endl;
    		}
    		else
    		{
    			cout << "Auto hat keine Lichter!" << endl;
    		}
    	}
    
    	void fahrer(int wert)
            //siehe oben
    	{
    		if(wert == 1)
    		{
    			cout << "Auto hat jetzt einen Fahrer!" << endl;
    		}
    		else
    		{
    			cout << "Auto hat keinen Fahrer!" << endl;
    		}
    	}
    };
    
    int main()
    {
    	int wert = 1;
    	Automobil zusammenbauen; //würdest du ein Auto "zusammenbauen" nennen?
    
    	zusammenbauen.raeder(wert);
    	zusammenbauen.motor(wert);
    	zusammenbauen.lichter(wert);
    	zusammenbauen.fahrer(wert);
    
    return 0;
    }
    

    [/quote]

    Alles in allem siehts nicht so aus, als hättest du den Sinn von Objekten in objektorientierten Sprachen wirklich verstanden. Wenn du Objekte an sich nicht verstanden hast, hast du auch Attribute nicht verstanden. (Sieht man, du benutzt sie nämlich garnicht) Dann machen für dich natürlich auch Konstruktoren und Destruktoren keinen Sinn. Wenn das das Ergebnis des "jetzt lerne ich C++"-Buches ist, dann ab in die Tonne und ein anderes Buch suchen...



  • Versuch doch mal ne Klasse Auto zu schreiben, die einen Kilometerstand hat. Nun soll es möglich sein verschiedene Autos anzulegen, z.B. ein Neues mit Kilometerstand = 0, oder ein gebrauchtes mit beliebigem Kilometerstand.



  • pumuckl schrieb:

    Wenn das das Ergebnis des "jetzt lerne ich C++"-Buches ist, dann ab in die Tonne und ein anderes Buch suchen...

    Ist es nicht.
    "Jetzt lerne ich C++" macht in Stunde 10

    SimpleCat::SimpleCat()
    {
      cout << "Konstruktor aufgerufen.\n";
      itsAge = 1;
    }
    

    vip@r scheint Folien zu "Jetzt lerne ich C++" zu benutzen, und weil die zu wenig sagen, sich die Begriffe mit "C++ von A bis Z" beibringen zu wollen.



  • [quote="volkard"]

    pumuckl schrieb:

    Ist es nicht.
    "Jetzt lerne ich C++" macht in Stunde 10

    vip@r scheint Folien zu "Jetzt lerne ich C++" zu benutzen, und weil die zu wenig sagen, sich die Begriffe mit "C++ von A bis Z" beibringen zu wollen.

    Also es tut mir leid, aber ich hab echt das Gefühl, dass ihr "neuen" Benutzern hier im Board gar keine Möglichkeit geben wollt, weiter zu helfen bzw. überhaupt zu helfen.

    Woher soll ich denn wissen, was Attribute, Objekte usw. sind wenn meiner Meinung nach die Folien und die Vorlesung grottig sind und das mittlerweile zweite Buch für C++ jetzt anscheinend wieder nix taugt?

    Ich weiß nicht aber anscheinend bin ich ja in letzter Zeit zu blöd für alles, wenn ich nach speziell diesem Board hier gehe...

    Ihr seid auf bestem Weg einen Benutzer zu vergraulen; aber das dürfte euch ja egal sein nicht wahr? 😃



  • Wenn es dir darum geht, sauberes C++ zu lernen und nicht nur die nächste Klausur zu bestehen, dann kann ich dir persönlich den C++ Primer empfehlen. In den FAQ findeste aber noch weitere Buchempfehlungen. Und Bücher hast du dringend nötig 😃



  • Dudemeister schrieb:

    Versuch doch mal ne Klasse Auto zu schreiben, die einen Kilometerstand hat. Nun soll es möglich sein verschiedene Autos anzulegen, z.B. ein Neues mit Kilometerstand = 0, oder ein gebrauchtes mit beliebigem Kilometerstand.

    Ich nenne also die Klasse Automobil. Was ich dann aber nicht merh verstehe, ist, warum die Klasse einen Kilometerstand hat. Muss ich den Kilometerstand durch über eine Methode von "außen" übergeben? Oder wie stellst du dir das vor?



  • Naja, ein Auto hat meistens nen Kilometerstand. Nicht über eine Methode, der Kilometerstand soll im Konstruktor übergeben werden.

    So dass man schreiben kann:

    Automobil gebrauchtWagen(2000);
        Automobil neuWagen(0);
    

    Aber du solltest dir Konstruktoren allgemein nochmal anschauen. Such einfach Beispiele oder Tutorials im Netz.



  • Also, das hier sollte doch jetzt schon mal gar nicht mehr so schlecht sein, oder?

    #include<iostream>
    using namespace std;
    
    class Automobil
    {
    private:
    
    public:
    	Automobil()		//Konstruktor
    	{
    
    	}
    };
    
    int main()
    {
    	Automobil gebraucht(20000), neu(0);		//im Argument steht der Kilometerstand
    
    return 0;
    }
    

    Konstruktoren tragen anscheinend den gleichen Namen wie die Klasse selbst und haben keinen Rückgabetyp. So viel hab ich schon mal selbst herausgefunden. Was dieser Konstruktor nun aber in diesem konkreten Fall machen soll ist mir schleierhaft...



  • Die Parameter des Konstruktors und die beim Aufruf übergebenen Argumente müssen natürlich zusammenpassen.

    Aber ich weiss nicht ob das hier viel bringt, du solltest dir wirklich in Ruhe die Thematik durchlesen, dann musst du auch nicht andauernd grundlegendste Dinge fragen.



  • vip@r schrieb:

    Also, das hier sollte doch jetzt schon mal gar nicht mehr so schlecht sein, oder?

    Naja, stell dir folgendes vor:

    Ich du bist Autohändler und willst deine Autos jetzt im Programm darstellen. Ein Auto hat für dich folgende wichtige Eigenschaften:
    Farbe, Zählerstand, Kaputt

    Dann könntest du das so verwenden wollen:

    Auto deinAuto(1000, "Rot", false);
    //1000 km Zählerstand
    //Farbe ist Rot
    //Kaputt ist false, also nicht Kaputt
    
    Auto meinAuto(0, "Schwarz", false);
    
    cout<<"Mein Auto ist "<<meinAuto.getFarbe()<<" lackiert\n";
    cout<<"Dein Auto ist "<<deinAuto.getFarbe()<<" lackiert\n";
    
    fahrOffRoad(meinAuto);
    fahrOffRoad(deinAuto);
    //Funktion die mit x Prozentiger Wahrscheinlichkeit das Auto kaputt macht
    //und den Zählerstand um y Kilometer erhöht
    
    if(deinAuto.isKaputt()) {
      cout<<"Dein Auto ist Kaputt gegangen :)\n";
    }
    if(meinAuto.istKaputt()) {
      cout<<"Mein Auto ist Kaputt genagen :(\n";
    }
    
    cout<<"Die Zählerstande lauten:\n";
    cout<<"Mein Auto: "<<meinAuto.getZaehlerstand()<<" km\n";
    cout<<"Dein Auto: "<<deinAuto.getZaehlerstand()<<" km\n";
    

    Und dazu jetzt die Funktion fahreOffRoad() schreiben und die Klasse Auto implementieren. Das ist eine nette Übung 🙂



  • Hab die Übung mal ausprobiert, Shade of Mine. Bei mir funktionierts. Ob's toll programmiert ist, weiß ich nicht:

    #include<iostream>
    #include<ctime>
    using namespace std;
    
    class Auto
    {
    private:
    	char wagenfarbe[10];
    
    public:
    	int kilometerstand;
    	bool wagenstatus;
    
    	Auto(int zaehlerstand, char farbe[10], bool status)
    	{
    		kilometerstand = zaehlerstand;
    		for(int i=0; i<10; i++)
    		{
    			wagenfarbe[i] = farbe[i];
    		}
    		wagenstatus = status;
    	}
    
    	char *getFarbe()
    	{
    		return wagenfarbe;
    	}
    
    	bool istKaputt()
    	{
    		return wagenstatus;
    	}
    
    	int getZaehlerstand()
    	{
    		return kilometerstand;
    	}
    };
    
    Auto fahrOffRoad(Auto automobil)
    {
    	int prozent, zaehlerstand_erhoehung, zaehlerstand;
    
    	srand(time(NULL));
    	prozent = rand() % 100 + 1;
    
    	if(prozent > 50)
    	{
    		automobil.wagenstatus = true;
    	}
    
    	srand(time(NULL));
    	zaehlerstand_erhoehung = rand() % 100 + 1;
    
    	automobil.kilometerstand = automobil.kilometerstand + zaehlerstand_erhoehung;
    
    return automobil;
    }
    
    int main()
    {
    	Auto deinAuto(1000, "Rot", false);
    	//1000 km Zählerstand
    	//Farbe ist Rot
    	//Kaputt ist false, also nicht Kaputt (wenn false, dann Auto nicht kaputt)
    	Auto meinAuto(0, "Schwarz", false);
    
    	cout << "Mein Auto ist " << meinAuto.getFarbe() << " lackiert\n";
    	cout << "Dein Auto ist " << deinAuto.getFarbe() << " lackiert\n";
    
    	//Funktion die mit x Prozentiger Wahrscheinlichkeit das Auto kaputt macht
    	//und den Zählerstand um y Kilometer erhöht
    	meinAuto = fahrOffRoad(meinAuto);
    	deinAuto = fahrOffRoad(deinAuto);
    
    	if(deinAuto.istKaputt())
    	{
    		cout << "Dein Auto ist Kaputt gegangen :)\n";
    	}
    
    	if(meinAuto.istKaputt())
    	{
    		cout << "Mein Auto ist Kaputt gegangen :(\n";
    	}
    
    	cout<< "Die Zaehlerstaende lauten:\n";
    	cout<< "Mein Auto: " << meinAuto.getZaehlerstand() << " km\n";
    	cout<< "Dein Auto: " << deinAuto.getZaehlerstand() << " km\n";
    
    return 0;
    }
    


  • Mir fällt grad was ganz komisches auf. Wenn ich das Programm schrittweise durchdebugge, dann bekomm ich für die Kilometerzahlen unterschiedliche Werte; wenn ich das Programm aber selbstständig bis zum Ende laufen lasse, dann hab ich beim Wert für zaehlerstand_erhoehung und automobil.wagenstatus (somit respektive "prozent") jeweils die gleichen Werte.

    Und das ist immer so der Fall!

    Könnt ihr mir sagen was das soll?



  • Der Ansatz ist schon gut, aber:
    - Member-Variablen sollten privat sein und nur über Methoden der Klasse geändert werden
    - für wagenfarbe hätte ich einen std::string verwendet, für wagenstatus einen enum (oder einen anderen Namen)
    - die Parameter-Übergabe und Rückgabe hat etwas Java-artiges

    PS: Was die Zufallswerte angeht: srand() ruft man nur einmal au, nicht vor jeder Zuallszahl.



  • CStoll schrieb:

    Der Ansatz ist schon gut, aber:
    - Member-Variablen sollten privat sein und nur über Methoden der Klasse geändert werden

    Ich hab jetzt mal zwei neue Methoden eingefügt; changeWagenstatus und changeKilometerstand.

    CStoll schrieb:

    - für wagenfarbe hätte ich einen std::string verwendet, für wagenstatus einen enum (oder einen anderen Namen)

    Ich bin das noch so aus C gewohnt; sorry...

    CStoll schrieb:

    - die Parameter-Übergabe und Rückgabe hat etwas Java-artiges

    Was meinst du damit? Ich kenn Java nicht...

    CStoll schrieb:

    PS: Was die Zufallswerte angeht: srand() ruft man nur einmal au, nicht vor jeder Zuallszahl.

    srand hab ich jetzt nur einmal drin!

    Hier mein neuer Code:

    #include<iostream>
    #include<ctime>
    #include<string>
    using namespace std;
    
    class Auto
    {
    private:
    	string wagenfarbe;
    	int kilometerstand;
    	bool wagenstatus;
    
    public:
    	Auto(int zaehlerstand, string farbe, bool status)
    	{
    		kilometerstand = zaehlerstand;
    		wagenfarbe = farbe;
    		wagenstatus = status;
    	}
    
    	string getFarbe()
    	{
    		return wagenfarbe;
    	}
    
    	bool istKaputt()
    	{
    		return wagenstatus;
    	}
    
    	int getZaehlerstand()
    	{
    		return kilometerstand;
    	}
    
    	int changeKilometerstand(int zaehlerstand)
    	{
    		kilometerstand = zaehlerstand;
    
    		return kilometerstand;
    	}
    
    	int changeWagenstatus(bool status)
    	{
    		wagenstatus = status;
    
    		return wagenstatus;
    	}
    };
    
    Auto fahrOffRoad(Auto automobil)
    {
    	int prozent, zaehlerstand_erhoehung, zaehlerstand;
    
    	srand(time(NULL));
    	prozent = rand() % 100 + 1;
    
    	if(prozent > 50)
    	{
    		automobil.changeWagenstatus(true);
    	}
    
    	zaehlerstand_erhoehung = rand() % 100 + 1;
    	automobil.changeKilometerstand(zaehlerstand_erhoehung + automobil.getZaehlerstand());
    
    return automobil;
    }
    
    int main()
    {
    	Auto deinAuto(1000, "Rot", false);
    	//1000 km Zählerstand
    	//Farbe ist Rot
    	//Kaputt ist false, also nicht Kaputt (wenn false, dann Auto nicht kaputt)
    	Auto meinAuto(0, "Schwarz", false);
    
    	cout << "Mein Auto ist " << meinAuto.getFarbe() << " lackiert\n";
    	cout << "Dein Auto ist " << deinAuto.getFarbe() << " lackiert\n";
    
    	//Funktion die mit x Prozentiger Wahrscheinlichkeit das Auto kaputt macht
    	//und den Zählerstand um y Kilometer erhöht
    	meinAuto = fahrOffRoad(meinAuto);
    	deinAuto = fahrOffRoad(deinAuto);
    
    	if(deinAuto.istKaputt())
    	{
    		cout << "Dein Auto ist Kaputt gegangen :)\n";
    	}
    
    	if(meinAuto.istKaputt())
    	{
    		cout << "Mein Auto ist Kaputt gegangen :(\n";
    	}
    
    	cout<< "Die Zaehlerstaende lauten:\n";
    	cout<< "Mein Auto: " << meinAuto.getZaehlerstand() << " km\n";
    	cout<< "Dein Auto: " << deinAuto.getZaehlerstand() << " km\n";
    
    return 0;
    }
    

    Das Problem, welches ich vorhin geschildert habe, dass die Werte nur unterschiedlich sind, wenn ich das Programm schritweise durchmach, besteht immer noch. Ich verstehe das überhaupt nicht!



  • Ich hab jetzt mal zwei neue Methoden eingefügt; changeWagenstatus und changeKilometerstand.

    Ich hätte da eher Funktionen erzeugt, die das ausdrücken was mit dem Wagen passieren soll: void fahre(int strecke); bzw. void beschaedige(); / void repariere();

    vip@r schrieb:

    CStoll schrieb:

    - für wagenfarbe hätte ich einen std::string verwendet, für wagenstatus einen enum (oder einen anderen Namen)

    Ich bin das noch so aus C gewohnt; sorry...

    Und dann die manuelle Kopierschleife ohne Rücksicht auf Null-Terminatoren *tststs*

    CStoll schrieb:

    - die Parameter-Übergabe und Rückgabe hat etwas Java-artiges

    Was meinst du damit? Ich kenn Java nicht...

    Ich habe mich auch nicht intensiv mit Java beschäftigt, aber dort ist es afair üblich, daß die Objekte unveränderlich sind und bei Bedarf modifizierte Kopien zurückgeben. In C++ kenne ich das eher so, daß man die Objekte per Referenz übergibt und direkt beeinflußt:

    void fahrOffRoad(Auto& automobil)
    {
        int prozent, zaehlerstand_erhoehung;
    
        prozent = rand() % 100 + 1;
    
        if(prozent > 50)
        {
            automobil.beschaedige();
        }
    
        zaehlerstand_erhoehung = rand() % 100 + 1;
        automobil.fahre(zaehlerstand_erhoehung);
    }
    

    CStoll schrieb:

    PS: Was die Zufallswerte angeht: srand() ruft man nur einmal au, nicht vor jeder Zuallszahl.

    srand hab ich jetzt nur einmal drin!

    Dort wird es immer noch bei jedem Funktionsaufruf ausgeführt. Setz den Aufruf lieber an den Anang der main().


Anmelden zum Antworten