#c #inheritance
Вопрос:
У меня есть a Cell
, который может хранить объекты CellContent
типа. CellContent
должен быть виртуальный класс. Из CellContent
меня должны выводиться классы Enemy
и Item
. Таким образом, идея состоит в том, чтобы сохранить указатель на CellContent
внутри Cell
. Вопрос в следующем: каков наилучший способ хранения указателя на производный класс в этих обстоятельствах?
Мое нынешнее решение не является элегантным, и я хочу его улучшить.
class Cell
{
public:
template<class T> void setCellContent(std::shared_ptr<T> cellContent)
{
_cellContent = std::dyanmic_pointer_cast<CellContent>(cellContent);
if (std::is_same<T, Enemy>::value = true) {
_cellContentType = CellContentType::ENEMY;
} else if (std::is_same<T, Item>::value = true) {
_cellContentType = CellContentType::ITEM;
}
}
template<class T> std::shared_ptr<T> getCellContent()
{
return std::dynamic_pointer_cast<T>(_cellContent);
}
CellContentType getCellContentType()
{
return _cellContentType;
}
std::shared_ptr<CellContent> _cellContent;
CellContentType _cellContentType;
}
int main()
{
auto enemy = std::make_shared<Enemy>();
Cell cell;
cell.setCellContent<Enemy>(enemy);
if (CellContentType::ENEMY == cell.getCellContentType()) {
cell.getCellContent<Enemy>();
} else if (CellContentType::ITEM == cell.getCellContentType()) {
cell.getCellContent<Item>();
}
}
Как я могу избежать использования if
этого уродливого, если в основном?
Комментарии:
1. Нормальный полиморфизм с виртуальными функциями?
2. Выглядит как классическое нарушение LSP .
3. Как правило, данный класс должен быть рассчитан либо на динамический, либо на статический полиморфизм. Здесь удаление шаблонов и использование виртуальных функций, по-видимому, являются подходящим выбором.
4. @Phil1970, Значит, все функции, которые могут использоваться в производном классе, должны быть объявлены виртуальными в базовом классе?
5. Да, именно так работают виртуальные функции. Виртуальное наследование само по себе является сложной темой, дополнительную информацию см. в вашем учебнике. Stackoverflow на самом деле не очень хорошая замена хорошему учебнику по C .
Ответ №1:
Все функции производного класса, которые необходимо вызывать (без приведения типа базового класса к типу производного класса вручную), должны быть объявлены virtual
в базовом классе (и переопределены в производном классе).