lundi 28 décembre 2020

Is polymorphism the best way to achieve this? (regarding function calls in derived classes)

I have a program that has four classes:

  • Vehicle (Base)
  • Automobile (Derived from Vehicle)
  • Car (Derived from Automobile)
  • Truck (Derived from Automobile)

At run-time, the user generates a Automobile object which is either a "Car" or "Truck" using a factory function:

Automobile *Automobile::make_automobile(std::string choice) {
    if (choice == "car")
        return new Car;
    else if (choice == "truck")
        return new Truck;
    else
        return nullptr;
}

Now, the "Car" class has three unique setters (and three matching getters):

  • Set_NumDoors()
  • Set_SeatMaterial()
  • Set_Shape()

The "Truck" class has one unique setter (and a matching getter):

  • Set_CargoWeight()

At first, these functions were only implemented in their own classes, but I could not call them at run-time since the object created was an "Automobile" object. I have solved this issue using virtual functions with local overrides. So now, the "Automobile" class all four functions (in virtual form), which by default do nothing. However, when called on an object, the local override performs the correct functionality. Below is an example, and it all works.

Definition in Automobile class

std::string defaultStatement = "Function call is invalid on current object";
    virtual int set_seatMaterial(std::string choice){
        std::cout << defaultStatement << std::endl;
        return -1;
    }

Override in Car class

    int set_seatMaterial(std::string choice) override { // override virtual base
        if (choice == "leather" || choice == "cloth"){
            seatMaterial = choice;
            return 0;
        }
        else
            return -1;
    }

I then use function pointers in main() to point to the required function as appropriate:

if (user_choice == "seat"){
            std::function<int(Automobile*, std::string)> choiceFunction = &Automobile::set_seatMaterial;
            choiceFunction(userVehicle, seatMaterial);
}

The only question I have is - is this the best way of achieving this functionality? It works but now I have declarations of every single function in the "Automobile" class, which already has its own getters/setters. It seems like duplication in a sense, although I understand the concept of polymorphism and its usefulness.

Or is there a better way to call a derived class function from a base class object?

Aucun commentaire:

Enregistrer un commentaire