I am fairly new to C++, but i have ran into an issue which i cannot seem to resolve. I will use cars to illustrate the problem, just to make things easier. Okay so lets say that i have a base class Car, and i have different brands that are inheriting from that class. Like so:
class Car
{
public:
Car();
};
class Ford: public Car
{
public:
Ford();
void drive();
void park();
};
The whole idea is to put all these different cars together in single a vector of the type Car. Like so:
vector<Car*> cars;
cars.push_back(new Ford());
cars.back()->drive(); //this won't work
How can i call the derived function on the base class instance? Note that i want to place these all in a single vector. The reason behind this is because i only want to use the last derived car class instance that has been added.(In this case the derived car class is ford). Also note that all car classes will have the same functions.
Even though the derived class can't call it in the base class, the base class can call it which effectively calls down to the (appropriate) derived class.
You would need to have the properties be declared as virtual on the base class and then override them in the derived class. You would either need to implement the property in the base class to return a default value (such as null) or to make it abstract and force all the derived classes to implement both properties.
base (C# Reference)The base keyword is used to access members of the base class from within a derived class: Call a method on the base class that has been overridden by another method. Specify which base-class constructor should be called when creating instances of the derived class.
If these functions are truly common to all the derived classes, then you have a common interface, so you should express this via the base class. To do so, you declare these functions as pure-virtual:
class Car {
public:
virtual void drive() = 0; // Pure-virtual function
};
class Ford : public Car {
public:
virtual void drive() { std::cout << "driving Ford\n"; }
};
...
vector<Car*> cars;
cars.push_back(new Ford());
cars.back()->drive(); //this will work
[On a side note, it's generally considered poor practice to have a vector of raw pointers, because it makes memory management tricky. You should consider using smart pointers.]
You have two options: either put a virtual drive() method in your Car definition, or cast the Car pointers to Ford pointers. Chances are you'll want to do the first.
class Car
{
public:
Car();
virtual void drive() { // default implementation}
};
Now you can drive() your Car! You can also make drive() a pure virtual function, like so:
class Car
{
public:
Car();
virtual void drive() = 0;
};
This basically means that there is no default implementation for drive(): it MUST be reimplemented in a subclass. The second way I mentioned, which, again, you probably don't want, but should be included for completeness, is to cast the pointer:
static_cast<Ford*>(cars.back())->drive();
This only works if you know beforehand that the Car is a Ford, however, and isn't much use in this scenario. You could also look into dynamic_cast.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With