Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looping through the derived classes by referencing the base class in C++

Tags:

c++

Sorry, if this has been asked before, just learning C++, had tried to search for it but not sure what the keyword is.

would it possible to do this?

class Car {
   public:
      void addColor(string c) {
          color = c;
      }

   private:
      string color;
}

class Honda:public Car {}
class Toyota:public Car {}

int main() {
    vector<Car> v;

    Honda *car1 = new Honda();
    car1.addColor("green");

    Toyota *car2 = new Toyota();
    car2.addColor("blue");

    v.push_back(car1);
    v.push_back(car2);

    for (int i = 0; i < v.size(); i++) {
        cout << v[i].color << endl; // should output green, blue
    }

}

if it's possible, what is the most right/effective way to do it?

EDIT 1

wow, thank you everybody!

like image 943
badcoder Avatar asked Oct 22 '22 06:10

badcoder


2 Answers

your vector always hold the base type, Car, sliced. Look up for 'polymorphic STL collection' 'polymorphic vector' or like to see how to store the derived classes.

here is an example

like image 61
Balog Pal Avatar answered Nov 02 '22 10:11

Balog Pal


There are two ways to handle this. Say we have the following class definitions:

#include <string>
class Car {
   public:
      Car(const std::string& color) : color(color) {}
      virtual ~Car() {}

      std::string color;
};

class Honda:public Car {};
class Toyota:public Car {};

Note I removed the setter and just made the member public. You may or may not want this, but for this example, it doesn't matter. Here is a way by allocating everything on the stack, and taking the address of these objects. This is fine in this example case (car1 and car2 don't need to outlive the main function). In real code this may not be true (i.e. the objects may need to outlive the function in which they are created, see further below):

#include <iostream>
#include <vector>

int main() {
    Honda car1("green");
    Toyota car2("blue");
    std::vector<Car*> cars; // vector of non-owning pointers

    v.push_back(&car1);
    v.push_back(&car2);

    for(auto& car : cars) {
        std::cout << car.color << "\n";
    }
}

Alternatively, allocate your objects on the heap:

int main() {
    std::vector<std::unique_ptr<Car>> cars; // vector of owning pointers

    v.emplace_back(new Honda("green"));
    v.push_back(new Toyota("blue"));

    for(auto& carptr : cars) {
        std::cout << carptr->color << "\n";
    }
}
like image 35
rubenvb Avatar answered Nov 02 '22 09:11

rubenvb