2011-12-29 5 views
0

T型の行列クラスMxNを作成し、それをインスタンス化して印刷しようとしました。 コードの最後に表示される問題(cout << m;) このコマンドは、別のマトリックスのいくつかのフィールドを含むマトリックスを印刷しました。実際にはmの最初の列はm2の最後の列と同じです。それはなぜですか?あるインスタンスが別のインスタンスに影響するべきではない

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <string> 
#include <stdexcept> 

using namespace std; 


template<typename T, int M> 
class matrix_helper { 
public: 
    T& operator[](int j) { 
     return data[j]; 
    } 

private: 
    T data[M]; 
}; 

template<typename T, int N, int M> 
class matrix { 
public: 
    explicit matrix(const vector<T>& v) { 
     if (v.size() != M * N) 
      throw invalid_argument("Incorrect input data"); 

     int i=0, j=0; 

     for (int k = 0; k != M*N; ++k) { 
      data[i][j] = v[k]; 
      ++i; 
      if (i == M) { // i:0..M 
       i = 0; 
       ++j; 
      } 
     } 
    } 
    matrix_helper<T,M> operator[](int j) { 
     matrix_helper<T, M> mh; 
     for(int i=0; i != M; ++i) { 
      mh[i] = data[j][i]; 
     } 
     return mh; 
    } 
    matrix<T,M,N>& operator+=(matrix<T,M,N>& m) { 
     for(int i=0; i != N;++i) 
      for(int j=0; j != M;++j) { 
       this->data[i][j] += m[i][j]; // or - should I rather use (*this)[i][j] += ... ??? 
      } 

     return *this; 
    } 

private: 
    T data[N][M]; 
}; 

template<typename T, int N, int M> 
ostream& operator<<(ostream& os, matrix<T,N,M> & m) { 
     int i=0, j=0; 
     for (int k = 0; k != M*N; ++k) { 
      os << m[i][j] << '\t'; 
      ++i; 
      if (i == M) { // i:0..M 
       i = 0; 
       ++j; 
       os << endl; 
      } 
     } 
     os << endl; 
} 



int rnd(int max = 20) { return rand() % max; } 
void print(int i) { cout << i << ' '; } 

int main() { 

    vector<int> u, v; 
    for (int i = 0; i != 20; ++i) u.push_back(i); 

    for (int i = 20; i != 40; ++i) v.push_back(i); 
    //for_each(u.begin(), u.end(), print); 


    matrix<int, 4,5> m(u); 
    matrix<int, 4,5> m2(v); 
    cout << m; // returns: 24 1 2 3 4,... Why not 0 1 2 3 4 ??? 


    cout << endl; 
    system("pause"); 
    return 0; 
} 
+0

OK、感謝を返す必要があります。コードビューを知らなかった。私は数分待って、答えが得られなければそこに投稿します... – Novellizator

+0

Codereviewは「なぜこれで私はそれがしないと思いますか」と尋ねるのではありません。 –

+1

@Tomy - いくつかの場所では 'matrix '、他の場所では 'matrix 'を使用します。それは目的ですか? –

答えて

4

あなたは[N][M]の配列を宣言し、それが[M][N]であるかのように初期化コードはそれを扱います。

-1

メモリをmatrix :: data配列に割り当てる必要があります。

あなたは、このように修正することができ、

T data[N][M]; =>あなたはメートルで平方メートルから値を参照するという事実は、あなたの行列からです

data.assign(M, std::vector<T>()); 
for (int x=0; x<M; ++x) 
    data[x].assign(N, T()); 
1

コンストラクタでstd::vector< std::vector<T> > data;

を調製するベクター、 ctorは、データ配列境界の外側に、近くにあるスタック上にあるものをすべて上書きして書き出します。正確にこの行:

data[i][j] = v[k]; 

は、配列の範囲外に書き込みます。

もご

ostream& operator<<() 

値に

関連する問題