Я много занимался векторной математикой и написал свой собственный шаблон для это.
Мои требования - много векторной математики (сложение, вычитание, масштабирование, перекрестное вычисление, и точка prod) также мне нужно иметь возможность передавать мой вектор как float [], чтобы openGL мог его использовать.
Я довольно долго этим пользовался, сегодня лектор увидел это и застонал. Было две вещи, которые он особенно ненавидел (одна из которых я понимаю): мое использование наследования, потому что оно, похоже, не соответствует стилю - это
. И мой кастинг (T *) это
, конечно, у него не было особого решения.
Первое: Наследование, мне нужно иметь возможность использовать vec2 для vec4, поэтому я спроектировал свои векторы следующим образом.
template<typename T>
Vector2D
{
public:
getX(), getY(), setX(), setY() ....
};
template<typename T>
Vector3D : public Vector2D<T>
{
public:
getZ(), setZ() ...
}
template<typename T>
Vector4D : public Vector3D<T>
{
public:
getW(), setW() ...
}
Почему это плохо? и tbh я не вижу, как это улучшить. Мне нужно (хочу) иметь возможность определять тип и иметь какие-то геттеры и сеттеры. Если бы я переставил его как
template<typename T, int _size>
VectorT
, я бы потерял свои .getX ()
, .setX ()
, и мне пришлось бы заменить его чем-то вроде .at ()
или []
. tbh Я предпочитаю удобочитаемость .getX ()
, хотя это упростит определение операторов.
Второе: Я могу понять, почему это плохо, но чтобы передать эти векторы в метод openGL, который ожидает массив с плавающей запятой, я перегрузил оператор splat
// Defined in Vector2D<T>
operator*() { return (T*)this; }
Насколько я понимаю, нет гарантии, что компилятор поместит переменные-члены x, y, z, w в начале класса, и если я не буду осторожен, я могу вместо этого передать v-таблицу. Однако я должен признать, что пока у меня не было проблем.
Единственный способ, которым я могу это избежать, - это поддерживать массив, который возвращается. Что, я полагаю, было бы проще, если бы я изменил их способ работы с векторами в первую очередь.