Einige OOP Probleme
-
Hi,
ich habe im Moment einige Probleme im Bereich von Abgeleiteten Klassen und ihren Zugriffsrechten. Ich erstelle in meiner main einen Zeiger auf die Basisklasse und weis ihm einem Car Object zu.(Dynamisch) Ich kann allerdings nicht auf die Funktion getMph() der abgeleiteten Klasse zuzugreifen.
Dabei bekomme ich einen Fehler das diese nicht existieren würde.
Auf die virtuelle Funktion move() kann ich ohne Probleme zugreifen, es wird auch die richtige aufgerufen. Ich habe schon einige Sachen Probiert, aber komme nicht auf den Fehler. Ich könnte natürlich auch gleich ein Car Object erstellen, aber auch in dem Beispiel von Marc++us in seinem Buch auf seite 65 macht er das genauso.
(Mit ziemlich ähnlichen Klassen)Die Abstrakte Basisklasse:
#ifndef VEHICLE #define VEHICLE #include <iostream> using namespace std; // Abstract Class: class Vehicle{ private: int m_speed; public: int getSpeed() const{return m_speed; } Vehicle(){cout<<"I am a Vehicle!"<<endl;} virtual void move(); }; #endif //VEHICLE
Und ihre zukünftig wichtigste Funktion:
#include "Vehicle.h" void Vehicle::move(){ cout<<"I am a Vehicle and I move!"<<endl; }
Jetzt die Abgeleitete Klasse:
#ifndef CAR #define CAR #include <iostream> using namespace std; #include "Vehicle.h" class Car : public Vehicle { private: int m_mph; public: virtual int getMph() const{return m_mph;} Car(int mph):m_mph(mph){cout << "I am a car!"<<endl;} virtual void move();} #endif //CAR
Und ihre wichtigste Funktion:
#include "Car.h" void Car::move(){ cout<<"I am a Car and I move!"<<endl; }
#include "Vehicle.h" #include "Car.h" int main(int argc, char *argv[]) { Vehicle *car1 = new Car(120); // Er ruft die virtuelle Funktion der Abgeleiteten KLasse Car ohne Probleme auf: car1->move(); // Doch er hat nur die Funktionen der Klasse Vehicle und die virtuelle Funktion // move der Abgeleiteten Klasse zur verfuegung! car1->getMph(); //error:'getMph' undeclared(first use this function) delete car1; cin.get(); return 0; }
Es kann sein das ich irgendetwas in seinem Beispiel übersehen habe,
in diesem Fall tut es mir leid, das ich euch nerve.
Das Programm habe ich (denke ich zumindest) ohne größere Veränderungen auf zwei Klassen gekürzt.
(Kann auch sein das ich etwas überlesen habe, allerdings finde ich nichts in dieser Richtung.)PS:getMph() virtuell zu machen hat auch keine Wirkung gezeigt.
Vielen dank im voraus.
MfG Max
-
static_cast würde dir helfen:
static_cast<Car>(carl)->getMph();
-
CarstenJ schrieb:
static_cast würde dir helfen:
static_cast<Car>(carl)->getMph();
Vielen dank.
Muss dass sein, oder geht das komfortabler?
(Sollte doch gehen, da car1 doch trotzdem ein Car Object ist?)MfG Max
-
dynamic_cast<Car*>(car1)->methodeDerAbgeleitetenKlasseCar();
Ist zwar nicht konfortabler, aber richtiger, IMO.
EDIT:
(Sollte doch gehen, da car1 doch trotzdem ein Car Object ist?)
Das weiss aber der Compiler nicht. Der Zeiger ist vom Typ Vehicle* und Vehicle stellt eben nicht alle Methoden bereit, die Car bereitstellt.
-
Entweder du gibst der Klasse Vehicle eine virtuelle methode getMph oder du legst gleich einen Zeiger auf ein Car an dem du dann auch ein Car zuweist. Das Vehicle einfach nach Car zu casten halte ich für unsinn, da es meiner auffassung von OOP wiederspricht. Entweder kann ein Vehicle getMph oder du hast in dem fall einfach kein Vehicle zu benutzen.
Gruß Mirauder Mo
-
Tja, wenn deine Klassen so aufgebaut sind, lässt sich das nicht vermeiden. Eine Möglichkeit wäre, getMph überall zu implementieren. Für Objekte, für die es nichts machen soll, macht es auch nichts:
getMph() {};
Dann brauchst du den Cast nicht mehr. Oder du erstellst einfach noch eine Klasse dazwischen, wenn möglich. Also in etwa so:
Vehicle (hat kein getMph()) ^ | | motorized Vehicle (hat getMph()) ^ ^ | | | | Car Truck
Das würd dann in etwa so aussehen:
motorizedVehicle *car1 = new Car(120); // Hat getMph() nonMotorizedVehicle *bikerl = new Bicycle(30); // hat es nicht... :clown:
-
Mirauder_Mo schrieb:
Entweder du gibst der Klasse Vehicle eine virtuelle methode getMph oder du legst gleich einen Zeiger auf ein Car an dem du dann auch ein Car zuweist. Das Vehicle einfach nach Car zu casten halte ich für unsinn, da es meiner auffassung von OOP wiederspricht. Entweder kann ein Vehicle getMph oder du hast in dem fall einfach kein Vehicle zu benutzen.
Gruß Mirauder Mo
Deshalb hat Marc++us also keine solche Methode eingebaut. Vielen dank an alle.
Ich kam nicht darauf das es an der zugefügten Methode getMph() liegen könnte, da ich mir ja sicher war das ich ein stinknormales Car Objekt erstelle und auf alles zugreifen kann.@CarstenJ: Danke, gute idee mit der zwischenklasse.
MfG Max
-
Eine Möglichkeit wäre, getMph überall zu implementieren. Für Objekte, für die es nichts machen soll, macht es auch nichts.
Fette Basisklassen sind auch keine Lösung. Das andere dagegen hört sich gut an.