Saya membuat beberapa kelas Vector2
(X & Y) dan Vector3
(X, Y & Z), tetapi saya tidak tahu apakah akan Vector3
mewarisi Vector2
, atau apakah akan mengimplementasikan kembali variabel anggota m_x
dan m_y
lagi? Apa pro dan kontra dari masing-masing pihak (warisan vs redefinisi).
Sunting: Saya menggunakan C ++ (VS2010).
c++
architecture
Tandai Ingram
sumber
sumber
Vector3
seharusnya hanya 3floats
sejauh memori yang bersangkutan. Bukan mengatakan itu tidak mungkin, hanya saja saya belum pernah melihatnya di mesin produksi.floats
. Anda tahu, YAGNI, KISS, semua itu.Vector2
,Vector3
danVector4
tanpa warisan danfloats
hanya benar-benar standar de facto di mesin game.typedef float real;
;).Jawaban:
Tidak seharusnya tidak. Satu-satunya hal yang akan Anda gunakan dari warisan adalah
x
dany
komponen. Metode yang digunakan diVector2
kelas tidak akan berguna diVector3
kelas, mereka kemungkinan akan mengambil argumen yang berbeda dan melakukan operasi pada sejumlah variabel anggota yang berbeda.sumber
Vector3
IS-NOT-AVector2
(jadi seharusnya tidak mewarisi), tetapiApple
IS-AFruit
(jadi mungkin mewarisi). Jika Anda cukup memutar pikiran, memilikiVector3
HAS-AVector2
di dalamnya, tetapi kehilangan kinerja dan kesulitan coding berarti Anda akan menulis kelas yang benar-benar terpisah untukVector3
danVector2
.Ada hal aneh yang dapat Anda lakukan dengan C ++ (Anda tidak menentukan bahasa, dan jawaban ini sebagian besar karena saya pikir senang melihat alternatif, meskipun saya tidak benar-benar percaya ini berguna dalam kebanyakan kasus.)
Menggunakan templat Anda dapat melakukan sesuatu seperti ini:
dan ini bisa digunakan seperti ini:
Seperti yang saya katakan, saya tidak berpikir ini berguna, dan itu mungkin akan mempersulit hidup Anda ketika Anda mencoba menerapkan dot / menormalkan / hal-hal lain dan mencoba untuk menjadi generik dengan sejumlah vektor.
sumber
Vector3f v
sedikit lebih kembungVector3<float> v
typedef
pergi.Terlepas dari kecepatan, pertanyaan pertama yang harus Anda bertanya pada diri sendiri ketika melakukan setiap warisan adalah jika Anda akan menggunakan mereka polymorphically. Lebih khusus lagi, apakah ada situasi di mana Anda dapat melihat diri Anda menggunakan
Vector3
seolah-olah ituVector2
(yang, dengan mewarisi darinya, Anda secara eksplisit mengatakan bahwa Vector3 "is-a" Vector2).Jika tidak, maka Anda tidak harus menggunakan warisan. Anda seharusnya tidak menggunakan warisan untuk membagikan kode. Itulah gunanya komponen dan fungsi eksternal, bukan berarti Anda akan membagikan kode apa pun di antara mereka.
Yang sedang berkata, Anda mungkin ingin cara mudah untuk mengubah
Vector3
s keVector2
s, dan dalam hal ini Anda dapat menulis operator yang berlebihan yang secara implisit akan memotongVector3
ke aVector2
. Tetapi Anda tidak seharusnya mewarisi.sumber
Vector2
tetapi mewarisi dari pangkalanVector<N>
? Itu masuk akal. Selain itu, mengapa warisan secara otomatis berarti perilaku polimorfik? Salah satu hal terbaik tentang C ++ adalah Anda dapat memiliki warisan biaya nol. Tidak perlu menambahkan setiap metode virtual (termasuk destructors virtual) di dasarVector<N>
kelas.Tidak, karena setiap metode perlu ditimpa juga, Anda tidak akan menggunakan pewarisan darinya.
Jika ada sesuatu, mereka berdua bisa mengimplementasikan antarmuka vektor. Namun, karena Anda mungkin tidak ingin menambahkan / sub / dot / dst antara Vector2 dan Vector3 ini akan memiliki efek samping yang tidak diinginkan. Dan memiliki parameter yang berbeda dll akan merepotkan.
Jadi saya benar-benar tidak dapat melihat pro dari warisan / antarmuka dalam hal ini.
Contohnya adalah kerangka Libgdx, di mana Vector2 dan Vector3 tidak ada hubungannya satu sama lain, selain memiliki jenis metode yang sama.
sumber
Jika Anda berencana untuk menggunakan array SIMD kemungkinan yang terbaik. Jika Anda masih ingin menggunakan overloading operator, Anda dapat mempertimbangkan untuk menggunakan antarmuka / mixin untuk mengakses array yang mendasarinya - misalnya, di sini adalah titik awal yang hanya memiliki (belum teruji)
Add
.Perhatikan bagaimana saya belum memberikan
X
/Y
/Z
, masing-masingVectorX
kelas akan mewarisi langsung dari satu ini - untuk alasan yang sama yang ditentukan oleh orang lain. Namun, saya telah melihat array yang digunakan sebagai vektor berkali-kali di alam liar.Penafian: C ++ saya mungkin payah, sudah lama sejak saya menggunakannya.
sumber
_aligned_malloc
berarti bug yang saya buka bukan bug?__m128
register, Anda harus menggunakannya_mm_loadu_ps
. Kelas sampel yang baik ada di sini di bawah "vectorclass.zip"_mm_loadu_ps
akan bekerja untuk Anda dengan struct itu (di mana_mm_load_ps
tidak akan). Saya juga menambahkan saran Anda - silakan mengedit pertanyaan jika Anda merasa saya menggonggong pohon yang salah (sudah lama sejak saya menggunakan C [++]).Lain con serius untuk memiliki Vec3 mewarisi dari Vec2 atau, bisa dibilang, untuk memiliki kedua mewarisi dari kelas Vector tunggal: kode Anda akan melakukan banyakoperasi pada vektor, sering dalam situasi kritis waktu, dan sangat penting bagi Anda untuk memastikan bahwa semua operasi itu secepat mungkin - jauh lebih banyak daripada banyak objek lain yang tidak cukup universal atau level rendah. Walaupun kompiler yang baik akan melakukan yang terbaik untuk meratakan overhead warisan, Anda masih lebih mengandalkan kompiler di sana daripada yang Anda inginkan; sebagai gantinya, saya akan membangun mereka sebagai struct dengan overhead sesedikit mungkin dan bahkan mungkin mencoba dan membuat sebagian besar fungsi yang menggunakannya (dengan pengecualian hal-hal seperti operator + yang tidak dapat membantu) menjadi global daripada metode pada struct. Optimalisasi awal umumnya direkomendasikan, dan dengan alasan yang sangat baik,
sumber