Я создаю пару классов Vector2
(X & Y) и Vector3
(X, Y & Z), но я не знаю, делать ли Vector3
наследование Vector2
, или заново реализовать переменные-члены m_x
и m_y
снова? Каковы плюсы и минусы каждой стороны (наследование против переопределения).
Изменить: я использую C ++ (VS2010).
c++
architecture
Марк Инграм
источник
источник
Vector3
должно быть всего 3,floats
если речь идет о памяти. Не сказать, что это невозможно, просто я никогда не видел этого в серийном движке.floats
. Вы знаете, ЯГНИ, ПОЦЕЛУЙ, все эти вещи.Vector2
,Vector3
ИVector4
без каких - либо наследования иfloats
только на самом деле де - факто стандартом в игровых системах.typedef float real;
;).Ответы:
Нет, не должно. Единственное , что вы хотите использовать от наследования является
x
иy
компонентов. Методы, используемые вVector2
классе, не будут полезны вVector3
классе, они, вероятно, будут принимать разные аргументы и выполнять операции с другим числом переменных-членов.источник
Vector3
IS-НЕ-АVector2
(так он не должен наследовать), ноApple
IS-AFruit
(так что он может наследовать). Если вы достаточноVector3
напряглись,Vector2
в нем есть HAS-A , но потеря производительности и сложность кодирования означают, что вы будете писать совершенно отдельные классы дляVector3
иVector2
.Есть любопытная вещь, которую вы можете сделать с C ++ (вы не указали язык, и этот ответ в основном потому, что я думаю, что приятно видеть альтернативы, хотя я не очень верю, что это полезно в большинстве случаев.)
Используя шаблоны, вы можете сделать что-то вроде этого:
и это можно использовать так:
Как я уже сказал, я не думаю, что это полезно, и это, вероятно, усложнит вашу жизнь, когда вы попытаетесь внедрить точки / нормализации / другие вещи и попытаться быть обобщенными с любым количеством векторов.
источник
Vector3f v
немного более распухшимиVector3<float> v
typedef
месте.Независимо от скорости, первый вопрос, который вы должны задать себе при выполнении любого наследования, это то, собираетесь ли вы использовать их полиморфно. Точнее говоря, есть ли ситуация, когда вы можете видеть себя, использующего,
Vector3
как если бы это былоVector2
(что, наследуя от него, вы явно говорите, что Vector3 "is-a" Vector2).Если нет, то вы не должны использовать наследование. Вы не должны использовать наследование для совместного использования кода. Для этого и нужны компоненты и внешние функции, а не то, что вы все равно будете делиться между ними кодом.
При этом вам могут потребоваться простые способы преобразования
Vector3
s вVector2
s, и в этом случае вы можете написать перегрузку оператора, которая будет неявно обрезатьVector3
aVector2
. Но вы не должны наследовать.источник
Vector2
а наследовать от базыVector<N>
? Это имеет смысл. Кроме того, почему наследование автоматически означает полиморфное поведение? Одна из лучших вещей в C ++ - то, что вы можете иметь нулевое наследование затрат. Нет необходимости добавлять какие-либо виртуальные методы (включая виртуальные деструкторы) в базовыйVector<N>
класс.Нет, так как каждый метод также должен быть переопределен, вы не будете использовать его наследование.
Если что-то, они оба могут реализовать интерфейс Vector. Однако, поскольку вы, вероятно, не хотите добавлять / sub / dot / dst между Vector2 и Vector3, это будет иметь нежелательные побочные эффекты. И иметь разные параметры и т. Д. Было бы хлопот.
Так что я действительно не вижу никаких плюсов наследования / интерфейса в этом случае.
Примером является среда Libgdx, где Vector2 и Vector3 не имеют ничего общего друг с другом, кроме как с использованием методов одного типа.
источник
Если вы планируете использовать SIMD- массивы , вероятно, лучше всего. Если вы все еще хотите использовать перегрузку операторов, вы можете рассмотреть возможность использования интерфейса / миксина для доступа к базовому массиву - например, вот отправная точка, которая имеет только (непроверенную)
Add
.Обратите внимание, что я не предоставил
X
/Y
/Z
, каждыйVectorX
класс наследовал бы напрямую от этого - по тем же причинам, которые были указаны другими людьми. Тем не менее, я видел множество массивов, используемых как векторы много раз в дикой природе.Отказ от ответственности: мой C ++ может быть отстой, прошло много времени с тех пор, как я его использовал.
источник
_aligned_malloc
означает, что ошибка, которую я открыл, на самом деле не ошибка?__m128
регистр, вы должны использовать_mm_loadu_ps
вместо этого. Хороший пример класса находится здесь под "vectorclass.zip"_mm_loadu_ps
должен работать для вас с этой структурой (где_mm_load_ps
не будет). Я также добавил ваше предложение - не стесняйтесь редактировать вопрос, если вы чувствуете, что я лаю не на том дереве (давно я использовал C [++]).Еще один серьезный довод в пользу того, чтобы Vec3 наследовал от Vec2 или, возможно, оба они наследовали от одного класса Vector: ваш код будет делать многоопераций над векторами, часто в критических по времени ситуациях, и в ваших интересах быть уверенными, что все эти операции выполняются настолько быстро, насколько это возможно - намного больше, чем для многих других объектов, которые не довольно универсальный или низкоуровневый. Хотя хороший компилятор сделает все возможное, чтобы сгладить любые издержки наследования, вы все равно больше полагаетесь на компилятор, чем хотели бы; вместо этого я бы построил их как структуры с минимальными накладными расходами и, возможно, даже попытался бы сделать большинство функций, которые их используют (за исключением таких вещей, как operator +, с которыми ничего не поделаешь), глобальными, а не методами STRUCT. Ранняя оптимизация, как правило, рекомендуется против
источник