Virtual -- Was passiert dann..
-
Hallo C++ Freunde,
ich habe hier mal ne Frage, ich sollte vom Lehrer aus, immer das virtual vorsetzen. Doch warum es notwendig ist, erkläre er uns nicht. Nun wenn ich das virtual vor void display() in der basisklasse setzte bekomme ich immer fehlermeldungen. erklärt mir mal an diesem programm wozu dies notwendig ist, und wie ich diesen fehler wegbekomme.
--------------------Konfiguration: uebung - Win32 Debug--------------------
Kompilierung läuft...
tiere.cpp
Linker-Vorgang läuft...
main.obj : error LNK2001: Nichtaufgeloestes externes Symbol "public: void __thiscall hund::display(void)" (?display@hund@@QAEXXZ)
main.obj : error LNK2001: Nichtaufgeloestes externes Symbol "public: void __thiscall tiere::display(void)" (?display@tiere@@QAEXXZ)
Debug/uebung.exe : fatal error LNK1120: 2 unaufgeloeste externe Verweise
Fehler beim Ausführen von link.exe.uebung.exe - 3 Fehler, 0 Warnung(en)
//tiere.h #include <iostream> #include <string> using namespace std; //Basisklasse Tiere class tiere { public: tiere(); ~tiere(); float getAlter(); void setAlter(float alta); string getGeschlecht(); void setGeschlecht(string geschl); virtual void display(); protected: float alter; string geschlecht; }; //Unterklasse Hund class hund : public tiere { public: hund(); ~hund(); int getBeine(); void setBeine(int bein); void display(); private: int beine; };//tiere.cpp #include "tiere.h" //Basisklasse Tiere tiere::tiere() { cout << "Baue Basisklasse auf" <<endl; } tiere::~tiere() { cout << "Zerstöre Basisklasse "; } float tiere::getAlter() { return alter; } void tiere::setAlter(float alta) { alter=alta; } string tiere::getGeschlecht() { return geschlecht; } void tiere::setGeschlecht(string geschl) { geschlecht=geschl; } void tiere::display() { cout <<"--------------------------------------" <<endl; cout <<" Das Tier ist :" <<alter <<endl; cout <<" Das Tier ist ein: " <<geschlecht <<endl; } /* -------------Klasse Hund------------ */ hund::hund() { cout <<" Baue Objekte der Klasse Hund auf" <<endl; } hund::~hund() { cout <<" Zerstöre die Objekte der Klasse Hund" <<endl; } int hund::getBeine() { return beine; } void hund::setBeine(int bein) { beine=bein; } void hund::display() { cout <<"--------------------------------------" <<endl; cout <<"Das Tier hat : " <<beine <<endl; cout <<" Das Tier ist :" <<alter <<endl; cout <<" Das Tier ist ein: " <<geschlecht <<endl; }//main.cpp #include "tiere.h" float alta; string geschl; int bein; string neustart; int main() { int auswahl; tiere *zeiger; hund *zeiger2; cout <<"******************TIERE HUNDE GAME******************\n\n " <<endl; cout <<" Bitte wählen sie aus, (1) Tiere (2) Hund" <<endl; cin >>auswahl; switch (auswahl) { case 1: cout <<"Wie alt ist das Tier " ; cin >>alta; cout <<"Welches geschlecht hat das Tier "; cin >> geschl; zeiger= new tiere; zeiger->setAlter(alta); zeiger->setGeschlecht(geschl); zeiger->display(); break; case 2: zeiger2= new hund; cout <<"Wie viele Beine hat ihr Tier" ; cin >> bein; cout <<"Wie alt ist das Tier " ; cin >>alta; cout <<"Welches geschlecht hat das Tier "; cin >> geschl; zeiger2->setAlter(alta); zeiger2->setGeschlecht(geschl); zeiger2->setBeine(bein); zeiger2->display(); break; default: cout <<"Falsche auswahl" <<endl; } cout <<"Soll das Programm neugestartet werden ja (j) nein (n) " <<endl; cin>> neustart; if (neustart== "j") { system ("cls"); main(); } else { return 0; } return 0; }
-
Vielleicht hilft dir das weiter
http://ladedu.com/cpp/kapitel10
http://tutorial.schornboeck.net/virtual.htm
http://www.willemer.de/informatik/cpp/cppvirt.htmEDIT: Bist du sicher das du dich nicht blos irgendwo verschrieben hast? Ich hab mir den Quellcode jetzt nicht durchgelesen sondern hab ihn mir nur kopiert, aber bei mir funktioniert das Programm.
-
das programm funktioniert auch so, aber nur wenn ich das virtual vorsetzte , funktioniert es nicht mehr.. woran kann es denn liegen ?
-
Ja das Programm funktioniert bei mir auch wenn da
virtual void display();steht, so wie der Quellcode halt oben ist. Oder hast du das virtual noch irgendwo anders stehen wenn es nicht mehr funktioniert?
-
Auf jeden Fall sollte der Destruktor von tiere virtuell sein.
-
Vergessen wir mal die sache, und zwar wollte ich mit nur einem zeiger arbeiten,
nun sagte mein kollegen , ich soll alle elemente aus der unterklasse in die oberklasse setzen und dann vor diesen elementen ein virtual setzen ( ausgenommen konstruktor) wenn ich das so mache, sagt der compiler mir das die funktionen in der cpp fehlen, somit erstelle ich dann die get und set methoten in der cpp. , nun werden die werte in der main.cpp eingegeben. aber wenn ich in die unterklasse zugreifen will, geht alles über die basis, und dann von dort aus ( mit hilfe der virtual elemente ) in die unterklassen, oder wie soll ich das verstehen ??...
-
Hier ist mein cpp programm
#include <iostream> #include <string> using namespace std; class drucker { public: drucker(); virtual ~drucker(); float getKosten(); void setKosten(float k); virtual int getGeschwindigkeit(); virtual void setGeschwindigkeit(int geschw); protected: float kosten; int geschwindigkeit; }; class laserdrucker: public drucker { public: laserdrucker(); ~laserdrucker(); int getGeschwindigkeit(); void setGeschwindigkeit(int geschw); private: int geschwindigkeit; };#include <iostream> #include <string> #include "drucker.h" using namespace std; int main() { float k; int geschw; char neu; char aus; drucker *druck; cout << "Waehle deinen Drucker! (D)rucker oder (L)aserdrucker" << endl; cin >> aus; if (aus == 'D' || aus == 'L') { switch (aus) { case 'D': druck= new drucker; cout << "Kosten: "; cin >> k; druck->setKosten(k); cout << "Kosten sind " << druck->getKosten() << endl; delete druck; break; case 'L': druck=new laserdrucker; cout << "Kosten und Geschwindigkeit: "; cin >> k; cin >> geschw; druck->setKosten(k); druck->setGeschwindigkeit(geschw); cout << "Kosten sind " << druck->getKosten() << endl; cout << "Geschwindigkeit ist " << druck->getGeschwindigkeit() << endl; delete druck; break; default: break; } } else { cout << "Falscher Wert" << endl; cout << "Neustart? (j/n)"; cin >> neu; if (neu == 'j' || neu == 'J') { main(); } else {return 0;} } cout << "Neustart? (j/n)"; cin >> neu; if (neu == 'j' || neu == 'J') { main(); } else {return 0;} return 0; }#include "drucker.h" drucker::drucker() { float kosten=0; int geschwindigkeit=0; } drucker::~drucker() { } float drucker::getKosten() { return kosten; } void drucker::setKosten(float k) { kosten=k; } int drucker::getGeschwindigkeit() { return geschwindigkeit; } void drucker::setGeschwindigkeit(int geschw) { geschwindigkeit=geschw; } laserdrucker::laserdrucker() { int geschwindigkeit=0; } laserdrucker::~laserdrucker() { } int laserdrucker::getGeschwindigkeit() { return geschwindigkeit; } void laserdrucker::setGeschwindigkeit(int geschw) { geschwindigkeit=geschw; }
-
HILFEEEEEEEEEEEEEEEEEEEEEEEEEee, vielleicht habe ich meine Frage schlecht gestellt.
Undzwar habe ich vorher immer mit mehreren Zeigern gerarbeitet
pro klasse ein zeiger. Somit konnte ich auf jedes elemente der klassen zugreifen,
nun sollte ich die eigenschaften der unterklassen zusätzlich in die oberklasse einfügen, doch dies (virtual) ausgenommen konstruktor und dekonstruktor.... !
beim ausführen, sagt mir der compiler ich soll in der .cpp die eingeschaften mit ausarbeiten ( weiß nicht wie man das nennt ) hund::getBeine(), das meinte ich, aber wenn ich nun in der main.cpp werte eingebe, so werden diese werte doch an die basisklasse weitergegeben, und nicht an die unterklasse, meiner meinung nach brauch ich dann doch gar keine unterklassen, oder wie mach ich das ?
-
Hatten wir so etwas ähnliches nicht vor kurzem?
http://www.c-plusplus.net/forum/viewtopic-var-t-is-146946.html
Anderer Fragesteller, aber sieht mir fast nach der gleichen Aufgabe aus. Ich frage mich wirklich in welcher Schule man so einen Mist lernt (sorry, nicht böß gemeint).
Also, erst einmal machen diese Zeilen in laserdrucker überhaupt keinen Sinn:
int getGeschwindigkeit(); void setGeschwindigkeit(int geschw); private: int geschwindigkeit;Diese Funktionalität ist in drucker bereits vorhanden und wird somit an laserdrucker vererbt.
Diese beiden Funktionen wären nur dann sinnvoll, wenn ein laserdrucker die Geschwindigkeit in irgendeiner Weise anders behandeln würde als ein gewöhnlicher drucker.
Wenn das so wäre, könnte man irgendwo einen neuen Laserdrucker anlegen und eine Zuweisung zu einem drucker-Zeiger durchführen:
drucker *Drucker = new laserdrucker;Wenn man nun folgenden Aufruf verwendet:
Drucker->SetGeschwindigkeit (10);wird die setGeschwindigkeit-Funktion von laserdrucker aufgerufen und nicht die von drucker (und das obwohl Drucker ein Zeiger vom Typ drucker ist). Genau das ist es, was das virtual bedeutet.
Alle Klarheiten beseitigt?
-
jo danke, ich wollte mich bei allen bedanken die mir immer geantwortet haben, es hat mich weiter gebracht, als in dem ganzen jahr in der schule ;)...
ich hatte heute 6 std c++ prüfung... 3 theorie 3 praxis.. theori = bool- shit
und praxis (ganz cool)hat alles funktioniert..
ich habe die prüfung mal gespeichert, ich packe die später mal on,
wäre cool wenn man das irgendwie verfeinern könnte, damit man nicht so viel schrieben muss. also in 3 zeilen irgendwie alles
ich meine damit etwas kürzer.. als ich das habe... also thx nochmal ..
-
Flipper schrieb:
ich sollte vom Lehrer aus, immer das virtual vorsetzen.
Ich wäre froh, wenn meine Lehrer sowas sagen würden. Doch die kennen sowas nicht. Die können nur das "schwarz-weiße" C++.

-
Falls Dich immer noch interessiert, was genau "virtual" macht, etwas einfach und recht gut für Anfänger beschrieben findest Du das auf folgenden Seiten:
http://www.mathematik.uni-marburg.de/~cpp/
Dort kannst Du Dich mal über das Inhaltsverzeichnis zur Vererbung und dann zur Virtualität durchclicken. Dort ist ein sehr schönes Beispiel anhand dessen das ziemlich gut erklärt ist, was Dein virtual eigentlich macht.mfg Maddin