Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I want a vector of derived class pointers as base class pointers

Tags:

In C++, the vector class stores an array of objects. In this case, I am storing pointers to derived class objects (Dogs). At some point, I want to treat this vector as pointers to objects of the base class (Animals). This is the "right"/non controversial way right? Why can't I do this?

#include <vector> using namespace std;  class Animal { };  class Dog : public Animal { };  int main(int argc, char *argv[]) {     vector<Dog*> dogs;     dogs.push_back(new Dog());     dogs.push_back(new Dog());     vector<Animal*> animals = dogs; // This doesn't seem to work.      // This is really what I want to do...     vector<Animal*> all_animals[] = {dogs, cats, birds}; } 

The error:

Untitled.cpp:11:18: error: no viable conversion from 'vector<class Dog *>' to 'vector<class Animal *>'     vector<Animal*> animals = dogs;                     ^         ~~~~ /usr/include/c++/4.2.1/bits/stl_vector.h:231:7: note: candidate constructor not viable: no known conversion from 'vector<Dog *>' to 'const std::vector<Animal *, std::allocator<Animal *> > &' for 1st argument   vector(const vector& __x)   ^ 
like image 892
SharkCop Avatar asked Aug 14 '13 04:08

SharkCop


People also ask

Can you convert a pointer from a derived class to its base class?

[19.4] Is it OK to convert a pointer from a derived class to its base class? Yes.

Can a derived class become a base class?

Inheritance enables you to create new classes that reuse, extend, and modify the behavior defined in other classes. The class whose members are inherited is called the base class, and the class that inherits those members is called the derived class. A derived class can have only one direct base class.

Can we assign derived class object to base?

In C++, a derived class object can be assigned to a base class object, but the other way is not possible.

How do you store vectors of pointers?

You can store pointers in a vector just like you would anything else. Declare a vector of pointers like this: vector<MyClass*> vec; The important thing to remember is that a vector stores values without regard for what those values represent.


1 Answers

There is a copy constructor for a std::vector but it requires you to copy the exact same type of vector. Fortunately, there is another constructor which takes a pair of iterators and adds all the elements in the range, so you can do this:

vector<Animal*> animals(dogs.begin(),dogs.end()); 

This creates a new vector of Animal pointers by iterating through each Dog pointer. Each Dog pointer is converted to an Animal pointer as it goes.

Here is a more complete example (using C++11):

#include <vector>  struct Animal { };  struct Dog : Animal { };  struct Cat : Animal { };  struct Bird : Animal { };  int main(int,char**) {   Dog dog1, dog2;   Cat cat1, cat2;   Bird bird1, bird2;   std::vector<Dog *> dogs = {&dog1,&dog2};   std::vector<Cat *> cats = {&cat1,&cat2};   std::vector<Bird *> birds = {&bird1,&bird2};   std::vector<std::vector<Animal *>> all_animals = {     {dogs.begin(),dogs.end()},     {cats.begin(),cats.end()},     {birds.begin(),birds.end()}   }; } 
like image 135
Vaughn Cato Avatar answered Oct 19 '22 13:10

Vaughn Cato