Доступ к производным элементам из вектора базового типа
Скажем, у меня есть такая ситуация:
class Vertex
{
public:
Position position;
Normal normal;
Texcoord texcoord;
int boneID;
};
class VertexSkinned: public Vertex
{
public:
float boneWeights[3];
int boneIDs[3];
};
class VertexMorphed: public Vertex
{
public:
Position posTargets[3];
Normal normTargets[3];
Texcoord texcoordTargets[3];
};
std::vector<Vertex> vertices;
VertexSkinned vs;
VertexMorphed vm;
Vertex v;
vertices.push_back( vs );
vertices.push_back( vm );
vertices.push_back( v );
// This is illegal right? But how would I go about achieving the desired effect
float someFloat = vertices.front().boneWeights[2];
Вопрос в комментарии. Я редко когда-либо использовал наследование и думал, что мог бы найти здесь полезное применение, хотя это кажется невозможным.
Я предполагаю, что использование вектора указателей, а затем динамическое приведение к производному классу работает? Это не то, что я хочу сделать, хотя.
3 ответа
Я не вижу никакой другой опции, кроме хранения указателей и dynamic_cast позже, чтобы получить производный объект. Если вы хотите сделать что-то подобное, не можете ли вы иметь 3 разных вектора, каждый из которых имеет свой собственный тип. В этом случае нет необходимости указателя бизнеса.
У вас есть проблемы с нарезкой. sizeof(VertexSkinned) и sizeof(VertexMorphed) не равны sizeof(Vertex) и не могут быть вставлены в массив. Вместо этого используйте указатели
Чтобы получить доступ к члену производного класса, сначала необходимо определить, относится ли указанный элемент к производному типу. Одним из вариантов будет добавление в Base функции GetType или использование dynamic_cast
Когда у вас есть массив вершин, я предполагаю, что все вершины в массиве имеют один и тот же тип, что будет означать, что хранение указателей и выполнение dynamic_cast
это пустая трата времени. Когда вы знаете, что каждая вершина в массиве гарантированно будет, скажем, VertexSkinned
, вы также должны быть в состоянии использовать быстрее static_cast
,
Хранение указателей на отдельные вершины может ухудшить производительность, поскольку они не будут храниться в одном непрерывном блоке памяти.