Reputation: 101
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.
Upvotes: 9
Views: 8525
Reputation: 8788
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.
Upvotes: 4
Reputation: 122011
If all Car
classes have the same functions then declare them as pure virtual
in the base class Car
:
class Car
{
public:
Car();
virtual ~Car();
virtual void drive() = 0;
virtual void park() = 0;
};
This will allow the example code that uses vector
to work as posted.
Upvotes: 2
Reputation: 1258
You must put a virtual function.
A virtual function in the base class. A virtual function can be implemented in the sub class, so you can specialize the behaviour of the drive() for example.
You can find a faq (or tutorial) about virtual functions here:
http://www.parashift.com/c++-faq-lite/virtual-functions.html
Upvotes: 0
Reputation: 4184
You have to define the interface like:
class Car{
public:
Car();
virtual void moveForward(unsigned int speed) = 0;
virtual void moveBack(unsigned int speed) = 0;
//...
virtual ~Car();
};
Don't forget to make the destructor virtual. After that you just need to implement these methods in your child classes, and call them after. Also in vector you could use the shared_ptr or just pass the instances directly.
Upvotes: 0
Reputation: 389
May be if possible you can define base class as
class Car
{
public:
Car();
virtual void drive();
};
Upvotes: 0
Reputation: 272822
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.]
Upvotes: 9