konkrete Inhaltsfragen
Moderator: Moderatoren
Re: konkrete Inhaltsfragen
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
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
Re: konkrete Inhaltsfragen
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:
Hoffe mir kann einer sagen was ich hier falsch mache
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;}}
}
}
-
- Administrator
- Beiträge: 237
- Registriert: Mo 10. Mär 2008, 04:09
- Wohnort: Aachen
- Kontaktdaten:
Re: konkrete Inhaltsfragen
Moin.
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:
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
Woher weißt du das? Hast du das mit dem Debugger getestet oder vermutest du das nur?Chris087 hat geschrieben:Problem ist, dass er dabei die dTanken von "Fahrzeug" und nicht von "PKW" aufruft!
Der Fehler liegt vermutlich in der if-Bedingung (dGlobaleZeit == 2.5).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;}}
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)
Debugger versuchen das Problem eigenständig etwas einzukreisen.
Ansonsten solltest du betreffende Zeilen der Deklatation und der
Implementierung posten.
Gruß Christian
Re: konkrete Inhaltsfragen
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();
}
?
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();
}
?
Re: konkrete Inhaltsfragen
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?
Re: konkrete Inhaltsfragen
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
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.
Re: konkrete Inhaltsfragen
Danke für eure Hilfestellungen! ich hab jetzt den Parameter dMenge in die Funktionsdeklaration in der Fahrzeug.h geschrieben, jetzt funktionierts! Danke @ f r
Re: konkrete Inhaltsfragen
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:
und der Debugger unterbricht in einer "xstring" Headerdatei.
Der Code dazu:
In der vBearbeiten von Streckenende:
Der Wurf der Ausnahme:
Und der Catch:
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...
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.
Der Code dazu:
In der vBearbeiten von Streckenende:
Code: Alles auswählen
void Streckenende::vBearbeiten()
{
cout << p_ptFahrzeug->sGetName() << p_ptWeg->sGetName() << "Streckenende" << endl;
}
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)
}
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();}
}
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]
Re: konkrete Inhaltsfragen
Ich habe sozusagen eine konkrete Inhaltsfrage...
Dummerweise habe ich mein Skript in Aachen liegen lassen , 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...
Dummerweise habe ich mein Skript in Aachen liegen lassen , 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...
Re: konkrete Inhaltsfragen
Da..[gelöscht]
Zuletzt geändert von ChriWe am Di 2. Dez 2008, 01:08, insgesamt 1-mal geändert.