2016-03-18 3 views
1

EDITпреобразования в вектор указателей уникальных базового класса

В соответствии с просьбой, я обеспечиваю пример:

#include <iostream> 
#include <vector> 
#include <memory> 

using namespace std; 

class Animal 
{ 
    public: 
     virtual void printName() = 0; 
}; 

class Dog: public Animal 
{ 
    public: 
     virtual void printName() { cout << "Dog" << endl; } 
}; 

class Cat: public Animal 
{ 
    public: 
     virtual void printName() { cout << "Cat" << endl; } 
}; 

int main() 
{ 
    vector<vector<unique_ptr<Animal>> *> groups_of_animals; 

    vector<unique_ptr<Dog>> dogs; 
    vector<unique_ptr<Cat>> cats; 

    dogs.push_back(unique_ptr<Dog>(new Dog)); 
    dogs.push_back(unique_ptr<Dog>(new Dog)); 
    cats.push_back(unique_ptr<Cat>(new Cat)); 

    groups_of_animals.push_back(reinterpret_cast<vector<unique_ptr<Animal>> *>(&dogs)); 
    groups_of_animals.push_back(reinterpret_cast<vector<unique_ptr<Animal>> *>(&cats)); 

    for(auto &group: groups_of_animals) 
     for(auto &animal: *group) 
      (animal) -> printName(); 

    return 0; 
} 

Выход: Собака Собака Кошка

Пользуется переосмысливать бросание безопасным и оправданным здесь? Статический бросок не работает.

PS Я нашел эту тему: I want a vector of derived class pointers as base class pointers, но в моей ситуации я использую unique_ptr и хочу, я не хочу, чтобы обновить все вектора как только я обновить некоторый ребенок вектор. Я просто хочу иметь указатели на эти дочерние векторы.

+1

Возможно, вы можете показать пример ввода и вывода, потому что я не понимаю ваш вопрос, как написано. – erip

ответ

3

Вы не можете сделать это по той простой причине, что ни reinterpret_cast, ни static_cast, ни dynamic_cast не работают.

Если у вас есть:

class Superclass {}; 

и

class Subclass : public Superclass {}; 

Вы можете, при определенных обстоятельствах, использовать один из подходящей бросает бросить экземпляр одного к другому.

Но вы не можете отличить std::vector от одного до std::vector другого, так как кажется, что вы пытаетесь сделать здесь. Ни один из двух векторных классов не является прямым суперклассом или подклассом другого векторного класса. std::vector - это шаблон. Каждый экземпляр шаблона является уникальным его собственным классом, который не связан ни с одним другим экземпляром шаблона (если явно не объявлено как таковое, используя специализацию и т. Д.)

+0

Может быть, я что-то не понимаю, но на самом деле пытаюсь направить указатель на вектор дочерних классов * указатели * на указатель на вектор указателей базового класса *. То есть, я пытаюсь обработать вектор > как вектор >. Не вектор как вектор . Это еще недействительно? – user3496846

+1

Да, это все еще недействительно. Неважно, что содержит вектор. Класс, который вы выполняете, - это два разных вектора. std :: vector и std :: vector - два независимых класса, которые не связаны друг с другом. Неважно, что такое X или Y, или является ли X родителем или дочерним элементом Y или указывает на родительский или дочерний класс. Здесь рассматриваемые классы представляют собой два разных векторных класса. Полная остановка. Пример: «класс A {X * ptr;}» и «класс B {Y * ptr;}". Если X и Y являются родителями или дочерними элементами друг друга, это не означает то же самое для A & B. Это два независимых класса. –