2011-01-03 4 views
1

Я используюmatrix = * ((fxMatrix *) & d3dMatrix); //Зло?

matrix = *((fxMatrix*)&d3dMatrix); 

довольно долгое время. Он работал нормально, пока мой экран не стал черным и получил на моем столе ведро разочарования.

fxMatrix содержит 4 fxVectors. fxVector раньше был 16 байтами, но теперь это было неожиданно 20. Это было потому, что он унаследовал fxStreamable, который добавил vTable.

Так что одно решение, конечно, просто не наследовать fxStreamable и оставить комментарий, говорящий, что он всегда должен быть 16 байт и не больше.

Другим решением было бы сделать функции преобразования и полностью скопировать матрицу. Это делает его более безопасным, но оказывает влияние на производительность. Полагаю, это лучшая идея.

Другое решение - не конвертировать вообще и придерживаться D3DXMATRIX, но это делает двигатель непоследовательным, и мне лично очень не нравится эта идея.

Что вы думаете?

+0

Вы должны делать то, что является самым чистым, а не самым быстрым; они все равно не являются взаимоисключающими. – GManNickG

ответ

3

Если вы это сделаете, добавить или утверждения во время компиляции теста:

assert(sizeof(fxMatrix) == sizeof(D3DMatrix)); 

BOOST_STATIC_ASSERT(sizeof(fxMatrix) == sizeof(D3DMatrix)); 

Для бонусных баллов, это также можно проверить, что каждое значение находится в том же месте.

Но да, это злой (как ядерная энергия), поэтому вы должны либо обрабатывать его с соблюдением надлежащих мер предосторожности, либо вообще не делать этого. ;)

+0

Это может быть даже расширено, а вместо ошибки вызывать правильную функцию преобразования, а в другом случае '# else' просто оставить исходный код. – Mephane

+2

Вы не можете проверить sizeof с препроцессором, вам придется использовать вариант static assert. –

+0

@ Сильвен: Ах, спасибо. Исправлена. – Macke

4

Влияние функций преобразования может быть очень незначительным. Используйте это решение, если профайлер не сможет доказать, что это узкое место. Такие отбросы действительно довольно злые, иначе вам не придется спрашивать об этом.

3

Вы можете просто сделать explict оператор присваивания:

// Code Was this: 
matrix = *((fxMatrix*)&d3dMatrix); 

// Add the assignment operator 
class fxMatrix 
{ 
    // STUFF 
    fxMatrix& operator=(D3DXMATRIX const& rhs) 
    { 
     // Explicitly copy. 
      // Do in here what you were letting the compiler do before. 
     return *this; 
    } 
    // STUFF 
}; 
// New Code 
matrix = d3dMatrix; 
+1

Почему оператор присваивания вместо конструктора? – GManNickG

+0

@GMan: Вероятно, должны быть оба. Это просто похоже на задание для этой ситуации. Трудно сказать с таким маленьким снайпом. –

+0

Вам нужен только конструктор, потому что назначение уже будет работать. – GManNickG

0

наследоваться от обоих, и использовать C++ бросает. Затем компилятор C++ увидит ваше истинное намерение и выполнит настройку 4 байта. Вряд ли вы увидите эффект корректировки указателя на 4 байта.