9

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.

Dan
  • 101
  • 1
  • 4

6 Answers6

9

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.]

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
4

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.

Anthony
  • 8,570
  • 3
  • 38
  • 46
  • Yeah, i will be using the first method, but its nice to know that that there is another way. Thanks for the info! – Dan Apr 02 '12 at 11:53
  • 1
    @Anthony, I think that for the second method it would be better to use a dyanamic_cast instead of a static_cast – exs Feb 27 '18 at 20:21
2

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.

hmjd
  • 120,187
  • 20
  • 207
  • 252
0

May be if possible you can define base class as

class Car
{
    public:
       Car();
       virtual void drive();
};
Anerudhan Gopal
  • 379
  • 4
  • 13
0

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.

AlexTheo
  • 4,004
  • 1
  • 21
  • 35
0

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

felipe
  • 1,212
  • 1
  • 15
  • 27