I have a lot of types derivating from Component and I store a pointer to them in my map. But when I try to get a Component from the map and cast it to a specific type to use it, I get the compile error above. I don't understand why.
Потому что ваша функция закодирована неправильно.
Ваша функция извлечение Component*
указателя на карте, разыменование указателя для доступа только Component
части объекта (не полный производного типа), а затем пытается построить временный экземпляр производного класса с входом Component
.
Другими словами, ваш пример, по существу, как это сделать:
inline Color& getObject(const std::string& key)
{
TComponent *pcomp = _map.at(key);
Color tmp(*pcomp); // <-- error here
return tmp;
}
ошибка означает, что ваш Color
класс не имеет конструктор, который принимает Component
в качестве входных данных, поэтому он не может скомпилировать.
Даже если код сделал компиляции, он все равно будет неправильно, потому что вы возвращаете ссылку на временный объект, который разрушается при выходе из нее, так что абонент будет в конечном итоге с висячей ссылкой на недействительных памяти ,
Как указано @MikeVine в комментариях, вы можете написать функцию, как это исправить:
template<typename U>
inline U& getObject(const std::string& key)
{
return static_cast<U&>(*(_map.at(key)));
}
И это будет работать, так как он исключает строительство временного объекта, и возвращает ссылку на существующий объект, сохраненный на карте.
Вы также могли бы написать функцию, как это вместо:
template <typename U>
inline U& getObject(const std::string& key)
{
return *(static_cast<U*>(_map.at(key)));
}
Этот код бросает Component*
указатель на U*
указатель первого до этого разыменования для доступа к производный объект класса.
Если вы не уверены во время выполнения ли запрошенный компонент фактически запрашиваемый тип, вы могли бы добавить некоторые дополнительные обработки ошибок, чтобы убедиться, что перед его возвращением:
template <typename U>
inline U& getObject(const std::string& key)
{
U *ptr = dynamic_cast<U*>(_map.at(key));
if (!ptr) throw std::invalid_argument("");
return *ptr;
}
В качестве альтернативы:
template<typename U>
inline U& getObject(const std::string& key)
{
return dynamic_cast<U&>(*(_map.at(key)));
}
Попробуйте статическое кастинг на U & –
Черт, что сработало, я не могу поверить, что я не об этом, спасибо, очень много, мне пора спать – Roger
@Redleouf, это была опечатка или вы не думали что в качестве возможного ответа, когда вы разместили q uestion? –