Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
649 views
in Technique[技术] by (71.8m points)

c++ - I want a vector of derived class pointers as base class pointers

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)
  ^
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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()}
  };
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...