2012-05-11 8 views
0

このシナリオで呼び出されたものを私に案内する人はいますか?私は3番目のコンストラクタが呼び出されることを知っている次に自動割り当てオペレータの作成

mat4<float> matrix; 
float mf[4][4]; 

//fill the float matrix here 

matrix = mf; 

を呼び出す場合は、上記のコードで

template<class T> 
class mat4 { 
public : 

T matrix[4][4]; 

    mat4(); 
    mat4(vec4<T> i, vec4<T> j, vec4<T> k, vec4<T> t); 
    mat4(const T input_matrix[4][4]); 

    //~mat4(); 

    mat4<T> Transposed() const; 
    void Transpose(); 

    mat4<T> Inversed() const; 
    void Inverse(); 

}; 

は(それは明示的ではありません)が、何がその横に呼ばれているのですか?代入操作から作成された一時オブジェクトを受け取る行列のコピーコンストラクタ?私はカスタム代入演算子を作成する必要があるかどうかを議論しています。カスタム演算子はmat4に行列をコピーし、mat4への参照を返すだけですが、自動的に作成された代入演算子にオーバーヘッドがない場合は、それに固執します。

答えて

1

任意の適切なreturn value optimizationは、3番目のコンストラクタを呼び出すだけでこれを減らす必要があります。最適化を使用してコンパイルしている限り、可読性を減らしてこの場合のオーバーヘッドを減らす必要はありません。

また、カスタムコピーコンストラクタや代入演算子がコンパイラ生成のものよりもオーバーヘッドが少ない方法はわかりません。それらは最適化をさらに複雑にする可能性がある。

0

この行列がstd::vector<T>(16);の場合、暗黙的に生成された現代の代入演算子は、mfから作成された一時的な内容を "盗み"、2番目のコピーを避けるでしょう。古いコンパイラでは、このような代入演算子を自分で書くことができます(What is the copy-and-swap idiom?参照)。

しかし、この行列はデータメンバとして配列を保持します。書くことができる任意の代入演算子と同じように、暗黙的に生成された代入演算子は、実際にコピーする必要があります。個々に値をとる(または、Tがほとんどコピー可能な場合は単一のmemcpyで)。実際にはコンパイラは一時的に最適化を行い、mfから直接すべての16 Tsをmatrix.matrixにコピーすることができますが、単純なRVOよりもはるかに複雑な最適化です。 GCCは私のテストでそれをやっているようだ。