2016-09-30 2 views
0

私は私はマトリックスを利用したいクラスのマトリックスと別のクラスのカメラを持っている私のMatrixクラスは次のようになります。私はポインタの仕組みを誤解していますか?

class Matrix4f { 
    public: 
     Matrix4f() { 
      this->setMatrix(EMPTY); 
     } 

     Matrix4f(Matrix4f &m2) { 
      this->setMatrix(m2.matrix); 
     } 

     static Matrix4f& Matrix4f::identity() { 
      Matrix4f& identity = Matrix4f() ; 
      identity.setMatrix(IDENTITY); 
      return identity; 
     } 

     void setMatrix(float f[4][4]) { 
      for (int r = 0; r < 4; r++) { 
       for (int c = 0; c < 4; c++) { 
         this->matrix[r][c] = f[r][c]; 
       } 
      } 
     } 

     Matrix4f& operator=(const Matrix4f &m2) { 
      this->setMatrix(m2.matrix); 
     } 
    private: 
     float matrix[4][4]; 
     static float EMPTY[4][4] = { 
      { 0, 0, 0, 0 }, 
      { 0, 0, 0, 0 }, 
      { 0, 0, 0, 0 }, 
      { 0, 0, 0, 0 } 
     }; // initialize an empty array (all zeros); 
     static float IDENTIY[4][4] = { 
      { 1, 0, 0, 0 }, 
      { 0, 1, 0, 0 }, 
      { 0, 0, 1, 0 }, 
      { 0, 0, 0, 1 } 
     }; // initialize a identity (array) 
} 

そして私は私のカメラのクラスでこれを持っている:

class Camera { 
    public: 
     Camera() { 
      this->calculateProjection(); 
     } 

     Matrix4f* getProjection() { 
      return this->projection; 
     } 
    private: 
     Matrix4f* projection; 

     Matrix4f* calculateProjection() { 
      this->projection = &Matrix4f::identity(); 
      // modify this->projection... 

      return this->projection; 
     } 
    } 

カメラのインスタンスを作成してその投影を取得しようとすると、オブジェクトが破損しているように見えます(マトリックスは完全に大きな負の数で埋められます)。

私のコードがこのような誤動作を引き起こしているのは本当に混乱しています。
私は、コンパイラによって自動的に削除される参照を処理することはかなり確信しています。そして、それは恒等行列を扱うと思うが、実際には意味をなさない。

単位行列を投影行列にコピーしないでください。単位行列がガベージコレクションされるかどうかは関係ありません。

は、私は())(calculateProjectionを返す私は実際に単位行列が新たなMatrix4fを(作成することのいずれか ことで、このコードの作品を​​作ることができることを発見)して、それを返すOR getProjectionを作ります。
問題は、私は本当にどちらかをしたくないということです。
私はアイデンティティが新しいMatrix4fを構築するのを望ましくありません。なぜなら、それを破壊することに対処しなければならず、そのメソッドが高価であるため、getProjection()をcalculateProjection()したくないからです。 Projectionマトリクスは決して変化しません。あなたの

Matrix4f& Matrix4f::identity() { 
      Matrix4f& identity = Matrix4f() ; 
      identity.setMatrix(IDENTITY); 
      return identity; 
     } 


+1

「同一性」とは何ですか? – deviantfan

+2

そして、なぜカメラでポインタを使用していますか? – deviantfan

+2

クラス「Matrix」または「Matrix4f」の名前は何ですか? – Nawaz

答えて

2

は、ローカルオブジェクトへの参照を返します。 identity()が一度終了すると、オブジェクトはなくなります。

ヒープに割り当てる必要があります。

代わりに、私はポインタがどのように機能するかを誤解してる

... 
    private: 
    Matrix4f projection; 

    Matrix4f& calculateProjection() { 
     ... modify ... 
     return this->projection; 
    } 
    ... 
+0

私が理解できないことは、calculateProjection()メソッドの中にブレークポイントを置くと、Visual Studioは投影行列がすべての正しい値に完全に初期化されていることを示しています... getProjection()単にcalculateProjection()を返すと、コードが魔法のように動作しますが、恒等行列が死んではいけないので意味がありません。 –

+0

@ThomasPaineは未定義の動作領域にありますが、時にはうまく動作しません。 –

+0

'Matrix4f&identity = Matrix4f();'は適合するコンパイラでエラーを起こします。 MSVC –

1

あなたのクラスのカメラで行列を宣言?

多分。これは一時的なオブジェクト、およびそれへの参照を(参照がidentityと呼ばれる)を作成します

Matrix4f& Matrix4f::identity() { 
     Matrix4f& identity = Matrix4f() ; 
     identity.setMatrix(IDENTITY); 
     return identity; 
    } 

:あなたのコードは、私が見ることができるいくつかの問題があります。私は、一時オブジェクトがMatrix4f& identity = Matrix4f() ;の後に破棄されるかどうか、または関数が返るかどうかはわかりませんが、どちらの方法でも、関数が返る前に一時オブジェクトが破棄され、関数は破棄されたオブジェクトへの参照を返します。

this->projection = &Matrix4f::identity(); 

this->projectionその後、破壊された一時オブジェクトのアドレスに設定されています。

その後、破棄された一時オブジェクトにアクセスしようとし、意外にもガベージデータを取得しようとします。

また、identity(関数)は静的ではないため、Matrix4f::identity()と呼び出すことはできません。

+0

しかし、コンパイラはidentity()が投影行列に返す行列からデータをコピーしないでください。データがすでに投影にコピーされていた場合、identity()行列が破壊されるとどうして重要なのでしょうか? –

+0

ローカル変数への参照を返すことは、未定義の動作です。簡潔でシンプル。それをしないでください。 – PaulMcKenzie

+0

@ThomasPaine 'identity 'は' this-> projection'への割り当てまでに破壊されます。 (これはポインタの代入なので、とにかく行列データをコピーしません) –

関連する問題