简体   繁体   中英

c++ inheritance, polymorphism and storing objects

I was given a simple assignment which wasn't challenging at first, however gives me a headache and I can't solve one(two?) problem, which is storing objects (without slicing) and getting to the wanted functions.

I assume it is a problem of either polymorphism and virtualization, so to the point:

I have a class Vehicle:

class Vehicle 
{ 
protected: 
    int speed;
    int id;

public: 
    int getSpeed ();
    int getID();
};

and a class that inherits from it:

class SuperVehicle : public Vehicle
{
protected: 
    int acceleration; 

public:
    int getAcceleration();
    int getSomething();
    int setAcceleration(int number);
};

Now my aim is to get a list(or other type of storing) of all vehicles (including SuperVehicles), fill it randomly with either Vehicles or SuperVehicles, and then randomly get to the correct methods, like:

list<Vehicle*> listOfVehicles;
list<Vehicle*>::iterator VehiclesIterator;
for(int i = 0; i <5; i++)
{
    if (i % 2) listOfVehicles.push_back(new Vehicle());
    else listOfVehicles.push_back(new SuperVehicle());
}
while(true)
{
    randomVehicle = rand() % 5;
    for(VehiclesIterator = listOfVehicles.begin();
        VehiclesIterator != listOfVehicles.end(); VehicleIterator++)
    {
    if (VehicleIterator.getID() == randomVehicle) break;
    }
    if (randomVehicle % 2) randomFunction = rand() % 2;
    else randomFunction = rand() % 4;

    switch(randomFunction)
    {
    case 0: (*VehicleIterator)->getSpeed(); break;
    case 1: (...)
    case 2: (*VehicleIterator)->getAcceleration(); break
    case 3: (...)
    }
}

I don't care about the assignment. Just want to solve this, because thinking of the solution takes all my time. Appreciate all answers.

Assuming my comment about pojazd being Vehicle , and that the problem is accessing the additional function getAccelleration (etc) in the derived class SuperVehicle , then the solution is to either:

  1. Make the base-class have a virtual function that "does nothing" in the baseclass.
  2. Use dynamic_cast and check the result.

Example of solution 2:

SuperVehicle* sv = dyanmic_cast<SuperVehicle*>(*VehicleIterator);
if(sv)
{
    sv->getAcceleration();
}
else
{
    cout << "Not a supervehicle, don't try to get accelleration!" << endl;
}

Typically, it is frowned upon to use dynamic_cast (because it essentially destroys the flow of the code with a bunch of if-statements, especially when there are many derived classes). It is better to have base-classes that have empty/no-op functions and/or wrap the functionality such that the generic functionality can be maintained without casts and lots of if-statements.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM