Dan
Dan

Reputation: 101

C++ Call derived function from base class instance

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

Answers (6)

Anthony
Anthony

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

hmjd
hmjd

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

orochi
orochi

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

AlexTheo
AlexTheo

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

Anerudhan Gopal
Anerudhan Gopal

Reputation: 389

May be if possible you can define base class as

class Car
{
    public:
       Car();
       virtual void drive();
};

Upvotes: 0

Oliver Charlesworth
Oliver Charlesworth

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

Related Questions