#c #polymorphism #smart-pointers #rtti
Вопрос:
У меня есть массив базовых классов, элементы которого содержат дочерний класс. Проблема в том, что когда я пытаюсь получить доступ к дочернему классу в массиве, я получаю ошибку no operator "[]" matches these operands
при попытке сделать:
shared_ptr<P>amp; tmpP= (*arrayOfC)[(int)x][(int)y];
Я пытаюсь получить доступ к дочернему классу. Если я это сделаю:
arrayOfC[(int)x][(int)y]
тогда я смогу получить доступ к базовому классу, который мне не нужен.
Я пытался использовать dynamic_cast безрезультатно.
Массив является
shared_ptr<C> arrayOfC[800][600];
Это объявлено в другом заголовочном файле и также использует прямое объявление.
Вот как его спасают:
shared_ptr<P> childClassP= make_shared<P>(z, x, y);
arrayOfC[(int)x][(int)y] = std::move(childClassP);
Комментарии:
1.
std::dynamic_pointer_cast
? — cplusplus.com/reference/memory/dynamic_pointer_cast2. Я пробовал это, но где бы я это использовал, я думаю, что использовал это неправильно.
3.
auto tmpC_derived = std::dynamic_pointer_cast<C_derived>(arrayOfC_base[x][y]);
должен это сделать.4. Является ли C базовым классом или дочерним классом?
5. C — базовый класс, есть два дочерних класса.
Ответ №1:
Вам нужно использовать std::dynamic_pointer_cast
, плюс, вам также нужно иметь, по крайней мере, виртуальный деструктор в базовом классе, чтобы генерировать виртуальные таблицы, чтобы сделать классы полиморфно связанными.
#include <memory>
struct C {
virtual ~C() {}
};
struct P : public C {
};
std::shared_ptr<C> arrayOfC[8][6];
int main() {
auto derived_ptr = std::make_shared<P>();
int x {2};
int y {2};
arrayOfC[x][y] = std::move(derived_ptr);
// does not compile: std::shared_ptr<P> view = arrayOfC[x][y];
std::shared_ptr<P> view = std::dynamic_pointer_cast<P>(arrayOfC[x][y]);
return 0;
}
Видишь http://www.cplusplus.com/reference/memory/dynamic_pointer_cast/