konkrete Inhaltsfragen

Moderator: Moderatoren

midrantos
Beiträge: 170
Registriert: Sa 22. Mär 2008, 13:51

Re: konkrete Inhaltsfragen

Beitrag von midrantos » Mo 3. Nov 2008, 23:55

Das ist genau der klassische Fall an dem man den Sinn von "virtual" sehr gut erklären kann, auf jeden Fall hat der Tester sich bei mir direkt nach der Erklärung mit dem Zeiger direkt zufrieden gegeben und ist weiter gegangen.

Also nochmal, wenn eine Methode nicht virtual deklariert ist, und ich richte einen Zeiger auf ein Objekt von der Klasse der Methode ein, dann kann der Zeiger sinnvollerweise auch Objekte aus vererbten Klassen aufnehmen. Versucht man aber nun Methoden in vererbten Klassen zu überschreiben, so wird beim Aufruf der Funktion trotzdem immer die "Urfunktion" aufgerufen. Dies liegt daran, dass bereits vor Programmausführung anhand dem Zeigertyp festgelegt wird (der ja auf die Urklasse gerichtet ist), dass die Urmethode benutzt wird.
Ist die Methode nun virtual, wird genau dies erst zur Laufzeit entschieden, und es wird diejenige Methode ausgeführt, die zu dem aktuellen Objekt gehört, also hier die in der vererbten Klasse überschriebene Methode.

Ich hoffe das hilft :)

Chris087
Beiträge: 296
Registriert: Mi 21. Mai 2008, 13:00

Re: konkrete Inhaltsfragen

Beitrag von Chris087 » Di 4. Nov 2008, 00:33

danke, die erklärung ist super :) aber die dTanken ist in "Fahrzeug" schon als virtual deklariert! Trotzdem wird Fahrzeug::dTanken() aufgerufen (sieht man ja wenn man mit dem Mauszeiger dadrauf steht)! Hab ich das wirklich richtig implementiert?

Ich poste einfach mal etwas mehr von meinem Code:

Code: Alles auswählen

void vAufgabe_2()
{
	int AnzFahr, AnzPKW;
	string sName;
	double dMaxGeschwindigkeit, dVerbrauch, dTankinhalt, dTankvolumen;
		
	cout << "Wieviele PKW moechten sie erstellen?" << endl;
	cin >> AnzPKW;
	cout << endl;
	cout << "Wieviele Fahrraeder moechten sie erstellen?" << endl;
	cin >> AnzFahr;
	cout << endl;

	vector<Fahrzeug*> feld(AnzFahr+AnzPKW);	//Erzeugen des Vektors für alle Fahrzeuge
	

	// Abfrage der PKW-Eigenschaften und Erstellen der PKW (-> in den Vektor)
	for (int i=0; i < AnzPKW; i++)
	{
		cout << endl << "Daten fuer den " << i+1 << ". PKW eingeben" << endl; 
		cout << "Name: " << endl;
		cin >> sName;
		cout << "Hoechstgeschwindigkeit: ";
		cin >> dMaxGeschwindigkeit;
		cout << "Verbrauch: ";
		cin >> dVerbrauch;
		cout << "Tankstand: ";
		cin >> dTankinhalt;
		cout << "Tankvolumen: ";
		cin >> dTankvolumen;
		cout << endl;

		feld[i] = new PKW(sName, dMaxGeschwindigkeit, dVerbrauch, dTankinhalt, dTankvolumen);
	}


	// Abfrage der Fahrrad-Daten und Erstellen der Fahrräder (-> in den Vektor)
	for (int i=0; i<AnzFahr; i++) 
	{
		cout << "Daten fuer das " << i+1 << ". Fahrrad eingeben:" << endl; 
		cout << "Name: " << endl;
		cin >> sName;
		cout << "Hoechstgeschwindigkeit: ";
		cin >> dMaxGeschwindigkeit;
		cout << endl;

		feld[i+AnzPKW] = new Fahrrad(sName, dMaxGeschwindigkeit);
	}

	// Ausgabe aller Objektdaten
	vAusgabeHead();

	for (double i=0.5; i<=10; i+=0.5)
	{
		dGlobaleZeit = i;				// Erhöhen der globalen Uhr um eine halbe Stunde

		for (int j=0; j<(AnzFahr+AnzPKW); j++)
		{
			feld[j]->vAbfertigung();
			//feld[j]->vAusgabe();
		}

		// Auftanken nach 2.5 Stunden
		if (dGlobaleZeit == 2.5) 
			{for (int k=0; k<AnzPKW; k++)
		{cout << "Das " << k+1 << ". Auto wurde mit " << feld[k]->dTanken() << " Litern betankt." << endl << endl;}}
	}

}
Hoffe mir kann einer sagen was ich hier falsch mache :)

Christian Bredtmann
Administrator
Beiträge: 237
Registriert: Mo 10. Mär 2008, 04:09
Wohnort: Aachen
Kontaktdaten:

Re: konkrete Inhaltsfragen

Beitrag von Christian Bredtmann » Di 4. Nov 2008, 00:48

Moin.
Chris087 hat geschrieben:Problem ist, dass er dabei die dTanken von "Fahrzeug" und nicht von "PKW" aufruft!
Woher weißt du das? Hast du das mit dem Debugger getestet oder vermutest du das nur?
Chris087 hat geschrieben:

Code: Alles auswählen

// Auftanken nach 2.5 Stunden
      if (dGlobaleZeit == 2.5)
         {for (int k=0; k<AnzPKW; k++)
      {cout << "Das " << k+1 << ". Auto wurde mit " << feld[k]->dTanken() << " Litern betankt." << endl << endl;}}
Der Fehler liegt vermutlich in der if-Bedingung (dGlobaleZeit == 2.5).
Da mit double-Werten gearbeitet wird, muss man die Maschinen(un)genauigkeit
berücksichtigen. Deswegen sollte man besser überprüfen, ob der
Betrag der Differenz kleiner als ein Epsilon ist.

Zum Beispiel:

Code: Alles auswählen

if (fabs(dGlobaleZeit - 2.5) < 1E-10)
Falls es nicht daran liegen sollte, könntest du es erstmal mit dem
Debugger versuchen das Problem eigenständig etwas einzukreisen.
Ansonsten solltest du betreffende Zeilen der Deklatation und der
Implementierung posten.


Gruß Christian

Sophia
Beiträge: 193
Registriert: Mo 2. Jun 2008, 17:24

Re: konkrete Inhaltsfragen

Beitrag von Sophia » Di 4. Nov 2008, 07:48

Ich hatte mal das gleiche Problem, dass ich vom main Programm aus nicht auf dTanken zugreifen konnte.
Die Betreuer konnten mir mit dem virtual auch nicht weiterhelfen.
Seit dem steht die if-Abfrage in vAbfertigung der Klasse PKW und laut den Testwerten scheint es zu funktionieren...

if(fabs(dGlobaleZeit-2.5)<0.0001)
{
cout << "Einmal voll AUFTANKEN!!!";
dTanken();
}

?

K-Bal
Beiträge: 147
Registriert: Di 24. Jun 2008, 18:46

Re: konkrete Inhaltsfragen

Beitrag von K-Bal » Di 4. Nov 2008, 09:47

Hast du denn auch dTanken() als public deklariert? Und hast du daran gedacht, dass du eine Memberfunktion immer in Verbindung mit einer Instanz der Klasse aufrufen musst? :shock:

f r
Beiträge: 30
Registriert: Di 17. Jun 2008, 16:26

Re: konkrete Inhaltsfragen

Beitrag von f r » Di 4. Nov 2008, 13:14

Hallo zusammen

@ Chris087
Ich hatte heute genau das gleiche Problem, ich versuch mal meine Lösung zu erklären:
Als Deklaration in Fahrzeug.h habe ich: virtual double dTanken(double dMenge=0.0);
Bei mir wars wichtig den optionalen Parameter dMenge hinzuschreiben.
Dann wird bei vFahrzeuge->dTanken(); im Hauptprogramm die Funktion aus PKW aufgerufen.
Hoffentlich hilft es.

Chris087
Beiträge: 296
Registriert: Mi 21. Mai 2008, 13:00

Re: konkrete Inhaltsfragen

Beitrag von Chris087 » Di 4. Nov 2008, 14:11

Danke für eure Hilfestellungen! :) ich hab jetzt den Parameter dMenge in die Funktionsdeklaration in der Fahrzeug.h geschrieben, jetzt funktionierts! Danke @ f r :)

Benutzeravatar
[MD]
Beiträge: 389
Registriert: Mi 16. Apr 2008, 14:26

Re: konkrete Inhaltsfragen

Beitrag von [MD] » Fr 7. Nov 2008, 17:51

Hallo alle miteinander,

ich habe ein großes Problem, bei dem ich nicht weiterkomme:
Ich erhalte leider keine Ausgabe der jeweiligen Exceptionmeldung, sondern immer nur:

Code: Alles auswählen

Unbehandelte Ausnahme bei 0x1048b2ba (msvcp80d.dll) in Aufgabenblock_2.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xccccccf0.
und der Debugger unterbricht in einer "xstring" Headerdatei.

Der Code dazu:
In der vBearbeiten von Streckenende:

Code: Alles auswählen

void Streckenende::vBearbeiten()
{
	cout << p_ptFahrzeug->sGetName() << p_ptWeg->sGetName() << "Streckenende" << endl;
}
Der Wurf der Ausnahme:

Code: Alles auswählen

double FzgFahren::dStrecke(Fahrzeug *fahrobjekt, double dZeitraum)
{
	if ((p_ptWeg->dGetLaenge() - fahrobjekt->dGetGesamtStrecke()) - (dZeitraum * fahrobjekt->dGeschwindigkeit()) > 0)
		return (dZeitraum * fahrobjekt->dGeschwindigkeit()); // Gefahrende Strecke des Fahrzeugs
	else if ((p_ptWeg->dGetLaenge() - fahrobjekt->dGetGesamtStrecke()) < 0.0000000001)
	{
		Streckenende Wegende(p_ptWeg, fahrobjekt); // Fahrzeug am Wegende
		throw Wegende; // ->Exception wird geworfen
	}
	else 
		return (p_ptWeg->dGetLaenge() - fahrobjekt->dGetGesamtStrecke()); // Gibt RestWegLaenge an (dS(dTn)
}
Und der Catch:

Code: Alles auswählen

void Weg::vAbfertigung()
{
	ListFahrzeug::iterator itL; // Iterator
	for (itL = p_ptFahrzeug.begin(); itL != p_ptFahrzeug.end(); itL++) // Schleifendurchlauf ueber alle Elemente der Liste
	try {
		(*itL)->vAbfertigung(); // Zeiger aus dem Iterator wird dereferenziert und dann wird die Abfertigung aufgerufen
	}	catch (FahrAusnahme& Exception) {Exception.vBearbeiten();}
}
Woran kann das liegen, dass ich nicht die erwünschte Ausgabe erhalte??

EDIT:

Ok hab den Fehler gefunden. Hatte vergessen den abgeleiteten Variablen der Klasse Streckenende einen Wert zuzuweisen, somit wurde der Wurf zwar gefangen, die Variablen danach jedoch nicht besetzt und waren daher ohne Wert. Dies hatte zur Folge, dass bei der Ausgabe nichts wiedergegeben werden konnte...
Ciao [MD]

Timur
Beiträge: 92
Registriert: Di 22. Apr 2008, 23:02

Re: konkrete Inhaltsfragen

Beitrag von Timur » Sa 8. Nov 2008, 15:55

Ich habe sozusagen eine konkrete Inhaltsfrage...
Dummerweise habe ich mein Skript in Aachen liegen lassen :oops: , muss aber dringend am Wochenende noch den 3 Teil des 1. Aufgabenblocks fertig machen. Mir fehlt halt nur die konkrete Aufgabenstellung, weiß nur noch das man z.B den Ausgabeoperator überladen soll. Wäre jedenfalls sehr dankbar, wenn jmd so freundlich wäre und die Aufgabenstellung hochladen könnte...

Benutzeravatar
ChriWe
Beiträge: 61
Registriert: Mi 12. Mär 2008, 13:17

Re: konkrete Inhaltsfragen

Beitrag von ChriWe » Sa 8. Nov 2008, 16:38

Da..[gelöscht]
Zuletzt geändert von ChriWe am Di 2. Dez 2008, 01:08, insgesamt 1-mal geändert.

Antworten

Zurück zu „Praktikum Informatik II“