Не уверен, что вы имеете в виду. Похоже, вы храните объекты по значению, и у вас есть массив Base
. Это не сработает, потому что как только вы назначите Derived, этот объект будет преобразован в Base, и часть Derived объекта будет вырезана. Но я думаю, что вы хотите иметь массив указателей на базу:
Base * bases[NUM_ITEMS];
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases[i] = new Derived1;
else if(r == 1)
bases[i] = new Derived2;
// ...
}
Если вы когда-либо работали с указателями, вы поймете, что это задница, когда им трудно управлять ими, особенно обойтись и не потерять их, так как вам нужно будет вызвать delete для них, чтобы освободить память и вызвать деструктор объекты. Вы можете использовать shared_ptr, и он справится с этим для вас:
shared_ptr<Base> bases[NUM_ITEMS];
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases[i].reset(new Derived1);
else if(r == 1)
bases[i].reset(new Derived2);
// ...
}
Теперь вы можете передать bases[x]
другому shared_ptr, и он заметит, что вы получили более одной ссылки - он автоматически вызовет удаление, если последняя ссылка на объекты выйдет из области видимости. В идеале вы также должны заменить необработанный массив на std :: vector:
std::vector< shared_ptr<Base> > bases;
for(int i=0; i<NUM_ITEMS; i++) {
int r = get_random_integer();
if(r == 0)
bases.push_back(shared_ptr<Base>(new Derived1));
else if(r == 1)
bases.push_back(shared_ptr<Base>(new Derived2));
// ...
}
Тогда вы можете передавать вектор, не теряя его размера, и вы можете динамически добавлять к нему элементы по требованию. Получите размер вектора, используя bases.size()
. Подробнее о shared_ptr
здесь .
Преобразование из базового класса в производный класс должно выполняться только в случае крайней необходимости . Обычно вы хотите использовать метод под названием polymorphism
, что означает, что вы вызываете функцию по базовому указателю, но на самом деле она вызывает функцию, определенную в производном классе, с одинаковой сигнатурой (имя и параметры одного типа). и сказано override
это. Прочитайте статью в Википедии об этом. Если вам действительно нужно выполнить приведение, вы можете сделать это так для необработанного указателя:
Derived1 * d = &dynamic_cast<Derived1&>(*bases[x]);
Использование dynamic_cast гарантирует, что при приведении к неверному типу (т. Е. Типу, который вы приводите, не является тип, созданный и назначенный базовому указателю), вы получите исключение, выданное оператором. Для случая shared_ptr тоже есть способы:
shared_ptr<Derived1> d = dynamic_pointer_cast<Derived1>(bases[x]);
if(d) {
// conversion successful, it pointed to a derived. d and bases[x] point still
// to the same object, thus share it.
}