2

with the code displayed below i have created 4 classes(3 subclasses and one superclass), each of them having the same print_info() function. I have created pointer objects from each class and inserted them into a vector created with the superclass.

#include <iostream>
#include <string>
#include <vector>
#include <iterator>

using namespace std;

class Vehicle
{
    private:
        int wheels, max_speed;
        string model;
    public:
        virtual void print_info()
        {
             cout << "This is function print_info() in Vehicle (parent class)" << endl; 
        }
};

class Car: public Vehicle
{
    private:
        int doors, passengers;
    public:
        void print_info()
        {
             cout << "This is function print_info() in Car (child class)" << endl;
        }
};

class Bike: public Vehicle
{
    private:
        string owner;
        bool hasLights;
    public:
        string my_owner();
};

class Truck: public Vehicle
{
    private:
        float cargo_weight;
        int allowed_speed;
    public:
        void print_info()
        {
            cout << "This is function print_info() in Truck (child class)" << endl;
        }
};

int main()
{
    Vehicle *v1 = new Vehicle();
    Vehicle v2;
    Car c1;
    Car c2;
    Bike b1;
    Truck t1;
    Truck t2;

    vector <Vehicle> vvec;
    Vehicle *v = new Vehicle();
    Car *c = new Car();
    Bike *b = new Bike();
    Truck *t = new Truck();
    vvec.push_back(*v);
    vvec.push_back(*c);
    vvec.push_back(*b);
    vvec.push_back(*t);

    vector<Vehicle>::iterator iter = vvec.begin();
    while( iter != vvec.end()) 
    {
        iter->print_info();
        iter++;
    }

    v1 = &v2;
    v1->print_info();
    v1 = &c2;
    v1->print_info();
    v1 = &t2;
    v1->print_info();
    system("pause");

    return 0;
}

The wanted output is this:

This is function print_info in Vehicle (parent class)

This is function print_info in Car (child class)

This is function print_info in Vehicle (parent class)

This is function print_info in Truck (child class)

This is function print_info in Vehicle (parent class)

This is function print_info in Car (child class)

This is function print_info in Truck (child class)

Instead i am getting:

This is function print_info in Vehicle (parent class)

This is function print_info in Vehicle (parent class)

This is function print_info in Vehicle (parent class)

This is function print_info in Vehicle (parent class)

This is function print_info in Vehicle (parent class)

This is function print_info in Car (child class)

This is function print_info in Truck (child class)

I believe this is due to early binding but i don't know how to solve this!

1
  • You can't use vector <Vehicle> vvec; -- it will create slicing problems -- only the Base parts are copied and stored in the vvec. You need a vector of Vehicle* Commented May 5, 2018 at 16:00

3 Answers 3

3

You need to create vector of pointers vector <Vehicle*> vvec;, when you push_back like vvec.push_back(*v); you pass elements by value and it casts to Vehicle, so there won't be polymorphism because all elements of vector are just simple Vehicle objects, change to this:

//...
vector <Vehicle*> vvec;

Vehicle *v = new Vehicle();
Car *c = new Car();
Bike *b = new Bike();
Truck *t = new Truck();
vvec.push_back(v);
vvec.push_back(c);
vvec.push_back(b);
vvec.push_back(t);

vector<Vehicle*>::iterator iter = vvec.begin();
while( iter != vvec.end())
{
    (*iter)->print_info();
    iter++;
}
//...

And your output will be:

This is function print_info() in Vehicle (parent class)
This is function print_info() in Car (child class)
This is function print_info() in Vehicle (parent class)
This is function print_info() in Truck (child class)
This is function print_info() in Vehicle (parent class)
This is function print_info() in Car (child class)
This is function print_info() in Truck (child class)
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for the interest :)
2

This is a classic example of object slicing.

When you dereference the pointer to insert it to the vector vvec.push_back(*v), you convert it to the base class type. Therefore, it now behaves as a 'Vehicle'.

If you want to get the behavior you expected, try using vector <Vehicle*> vvec and vvec.push_back(v).

2 Comments

@FoivosAllayiotis re no offense alla theleis kapoion na sou exigei ti simvainei i theleis kapoion na sou grapsei ton kodika?
Εκατάλαβα το λάθος απλά επειδή έψαχνα το ώρες είπα να γράψω μπας και βοηθήσει κάποιος που ξέρει λίγα πράματα παραπάνω επειδή είμαι καινούργιος στον τομέα :)
1

What you want is polymorphism, so you have to either store Vehicle references or a Vehicle pointers. And, since you cannot store references in a vector, pointer is the way to go.

vector <Vehicle*> vvec;

Then simply push the pointers and calling print_info will trigger polymorphic behaviors

    vvec.push_back(v);
    vvec.push_back(c);
    vvec.push_back(b);
    vvec.push_back(t);

    vector<Vehicle*>::iterator iter = vvec.begin();
    while( iter != vvec.end())
    {
        (*iter)->print_info();
        iter++;
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.