• 締切済み

クラスの合成ができない

大学で数値計算をしており、Matrixクラスを作ったのですが他のクラスや構造体のメンバ変数に取り入れようとしてもできません。 以下のようなコードなのですがどうしてできないのでしょう? #include<iostream> using namespace std; class Matrix{ private: double **ptr; int Row,Col; public: Matrix(int i=1, int j=1);/* コンストラクタ */ Matrix(const Matrix &);/* コピーコンストラクタ */ ~Matrix();/* デストラクタ */ }; Matrix::Matrix(int Dim1,int Dim2) { Row=Dim1; Col=Dim2; for(int i=0;i<=Dim1;i++){ ptr[i]=(double*) new double[Dim2+1]; if(ptr[i]==NULL){ cerr<<"Memory Allocation Error.\n"; abort(); } } } Matrix::~Matrix() { for(int i=1;i<=Row;i++)delete [] ptr[i]; delete [] ptr; ptr=NULL; } struct Test{ Matrix A(3,3);//これはエラー }; int main() { Matrix B(3,3);//これは出来た return 0; }

みんなの回答

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.2

エラーになる原因は #1氏の通りですが Matrixのptrの初期化がうまくされていないように思います コンストラクタ内で ptr[i]=(double*) new double[Dim2+1]; と記述されていますが ptr[n]は確保されていません デストラクタ内の delete[] ptr; 後始末していますが 確保していませんのでおかしなことになるように思います

回答No.1

> なのですがどうしてできないのでしょう? struct Test の宣言時はMatrixをコンストラクトできないから。 コンストラクトできるのはTestのコンストラクト時(以降)。なので: struct Test {  Matrix A;  Test() : A(3,3) {} // ここでAを作る。 }

関連するQ&A

  • 自作の行列クラスを継承するさいにエラーがでます

    現在、c++の学習で、自作の基底行列クラスMatrixを作成し、このクラスを継承して新たにlduMatrixを作成する事を考えています。 が、継承し、 lduMatrix a( 3, 3); a = 3; とすると、 main.C:13: warning: passing ‘double’ for argument 1 to ‘lduMatrix::lduMatrix(int)’ というエラーがでてコンパイルできずにいます。その一方で、 lduMatrix a(3,3, 3.14); とするとコンパイルはとおり、lduMatrix行列の各要素(a[1][1]など)の値をプリントさせると、[[3.14]]の値が入っていることを確認しております。 どこが間違っているのか御指導いただけると幸いです。 以下、クラスの中身です。よろしくおねがいします。 《Class: Matrix》 #include <iostream> class Matrix{ private: //! Size of row and column in Matrix int row_, col_; //! Row pointers double** m_; //! Allocate function for row-pointers void allocate(); public: Matrix(); //! Constructor with given matrix size Matrix( const int, const int ); //! Constructor with given matrix size and value fro all elements Matrix( const int, const int, const double ); //! Destructor ~Matrix(); ・・・省略・・・ double* operator[]( const int ); double* operator[]( const int ) const ; void operator=( const double ); }; /* Private functions *********************************************** */ void Matrix::allocate() { m_ = new double* [row_]; m_[0] = new double [row_*col_]; for ( int i=1; i<row_; i++ ){ m_[i] = m_[i-1] + col_; } } /* Destructor ****************************************************** */ Matrix::~Matrix(){ delete[] m_[0]; delete[] m_; } /* Constructors **************************************************** */ // NULL constructor Matrix::Matrix() : row_(0), col_(0), m_(NULL) {} // Constructor with given matrix size Matrix::Matrix( const int row, const int col ) : row_(row), col_(col) { allocate(); } // Constructor with given matrix size and value for all elements Matrix::Matrix( const int row, const int col, const double s ): row_(row), col_(col) { allocate(); double* m = m_[0]; for ( int i=0; i<row_*col_; i++ ){ m[i] = s; } } 《省略》 /* Member operators ************************************************ */ double* Matrix::operator[]( const int i ){ return m_[i]; } void Matrix::operator=( const double t ){ double* m = m_[0]; int nm = row_*col_; for ( int i=0; i<nm; i++ ) { m[i] = t; } } 《Class: lduMatrix》 class lduMatrix : public Matrix{ public: lduMatrix(); lduMatrix( const int ); lduMatrix( const int, const double ); }; lduMatrix::lduMatrix() {} lduMatrix::lduMatrix( const int mSize ) : Matrix( mSize, mSize, 0.0 ) {} lduMatrix::lduMatrix( const int mSize, const double s ) : Matrix( mSize, mSize, s ) {}

  • エラーの原因が分かりません "undefined reference to"

    ライブラリのヘッダファイル matrix.h #ifndef MATRIX_H #define MATRIX_H #ifdef __cplusplus extern "C"{ #endif typedef struct{ int row,col; double *elements; } MATRIX; extern int matrix_error_code; extern void zero_matrix(MATRIX *a); extern void identity_matrix(MATRIX *a); extern void show_matrix(MATRIX *x); extern MATRIX multiply_matrix(MATRIX *a,MATRIX *b); extern MATRIX transposed_matrix(MATRIX *a); #ifdef __cplusplus } #endif #endif ライブラリのソースファイル matrix.c #include <stdio.h> #include <stdlib.h> #include <math.h> #include "matrix.h" int matrix_error_code = 0; void zero_matrix(MATRIX *a) { int i,size; double *p; size=a->row*a->col; if((p = malloc(sizeof(double)*size)) == NULL) { puts("メモリを確保できません."); exit(0); } a->elements=p; for(i=0;i<size;i++) *p++=0; } void identity_matrix(MATRIX *a) { int i; zero_matrix(a); for(i=0;i<a->row;i++) { *(a->elements+i*a->col+i)=1.0000; } } void show_matrix(MATRIX *x) { int i,j; for(i=0;i<x->row;i++) { for(j=0;j<x->col;j++) { printf("%3.4lf ",*(x->elements+i*x->col+j)); } printf("\n"); } printf("\n"); } MATRIX transposed_matrix(MATRIX *a) { MATRIX x; int i,j; double *p; if((p = malloc(sizeof(double)*(a->row*a->col))) == NULL) { puts("メモリを確保できません."); exit(0); } x.elements=p; x.row=a->col; x.col=a->row; for(i=0;i<x.row;i++) { for(j=0;j<x.col;j++) { *p++=*(a->elements+j*x.row+i); } } return x; } MATRIX multiply_matrix(MATRIX *a,MATRIX *b) { int i,j,k; double *p; MATRIX x; x.row=a->row; x.col=b->col; if((p = malloc(sizeof(double)*(x.row*x.col))) == NULL) { puts("メモリを確保できません."); exit(0); } x.elements=p; for(i=0;i<x.row;i++) { for(j=0;j<x.col;j++) { for(k=0;k<a->col;k++) { *p += *(a->elements+i*a->col+k) * *(b->elements+k*b->row+j); } } p++; } return x; } 動作確認のアプリケーションファイル test_matrix.c #include <stdio.h> #include "matrix.h" int main(void) { int i,j; MATRIX b,c,d,f; b.row=c.row=2; b.col=c.col=2; identity_matrix(&b); identity_matrix(&c); d=transposed_matrix(&b); show_matrix(&d); f=multiply_matrix(&b,&c); show_matrix(&f); return 0; } ライブラリのコンパイルまではエラーなしで出来るのですが、test_matrix.cをコンパイルすると、"undefined reference to '_transposed_matrix'"と、"undefined reference to '_multiply_matrix'"の2つが表示されてコンパイルができません。 どうかよろしくお願いします。

  • ポインタの指しているアドレスは同じなのに表示される内容が違う。

    行列に関するプログラムです。 ライブラリのヘッダファイル matrix.h #ifndef MATRIX_H #define MATRIX_H #ifdef __cplusplus extern "C"{ #endif typedef struct{ int row,col; double *elements; } MATRIX; extern int matrix_error_code; extern MATRIX zero_matrix(MATRIX a); extern MATRIX identity_matrix(MATRIX a); extern void func_matrix(MATRIX a); #ifdef __cplusplus } #endif #endif ライブラリのソースファイル matrix.c #include <stdio.h> #include <stdlib.h> #include <math.h> #include "matrix.h" int matrix_error_code = 0; MATRIX zero_matrix(MATRIX a) /*零行列をつくる*/ { int i,size; double *p; size=a.row*a.col; for(i=0;i<size;i++) { if((p = malloc(sizeof(double))) == NULL) { puts("メモリを確保できません."); exit(0); } *p=0; } a.elements=p-size; return a; } MATRIX identity_matrix(MATRIX a) /*単位行列をつくる*/ { int i; a=zero_matrix(a); for(i=0;i<a.row;i++) { *(a.elements+i*a.col+i)=1.0000; } return a; } void func_matrix(MATRIX a) { int i,j; double *p; printf("b.elementsの値:%p\n",a.elements); printf("b[1,1]の値:%lf\n",a.elements); } 動作確認用のアプリケーションファイル test_matrix.c #include <stdio.h> #include "matrix.h" int main(void) { int i,j; MATRIX b; b.row=2; b.col=2; b=identity_matrix(b); for(i=0;i<b.row;i++) { for(j=0;j<b.col;j++) { printf("%3.4lf ",*(b.elements+i*b.col+j)); } printf("\n"); } printf("\n\n"); printf("b.elementsの値:%p\n",b.elements); printf("b[1,1]の値:%lf\n",b.elements); func_matrix(b); return 0; } void func_matrix(MATRIX a)内のprintf("b.elementsの値:%p\n",a.elements);とtest_matrix.c内のprintf("b.elementsの値:%p\n",b.elements);で表示される値は同じなので、main関数のbがvoid func_matrix(MATRIX a)内のaに正しく引き渡されていると思うのですが、それぞれの次の行での、printf("b[1,1]の値:%lf\n",b.elements);とprintf("b[1,1]の値:%lf\n",a.elements);とでは表示される値が違い、理由がわからず困っています。 どうか回答をよろしくお願いします。

  • 3次元配列の動的確保

    2次元配列は、 // 動的確保 int **mat = new int*[row]; for(i = 0; i < row; i++) mat[i] = new int[col]; //解放 for(i = 0; i < row; i++) delete [] mat[i]; delete [] mat; で、生成と開放はできたのですが、3次元となると、途端にわからなくなります。 かれこれ1時間半は試行錯誤はしているのですが、たどり着きそうにありません。 どなたかご教授願います。

  • pythonで制作中のプログラムのエラー修繕と速度向上を行いたいのですが...

    こんにちは。いつもお世話になっております。 今回、file("filename.txt", "r")で読み込んだ多次元配列の中から、数字の合計が一番大きくなる長方形を探し出して合計をprintするプログラムを作っています。なんだか分かりにくい説明ですみません...。 例えば、 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 が読み込まれた配列だとしたら、左下の 9 2 -4 1 -1 8 を含む長方形内の数字の合計(9+2-4+1-1+8)が、この配列内の数字の合計の最大になります。この最大合計値を含む長方形を見つけ出して合計をprintさせたいのです。 自力で書いたものは以下です↓ myFile = file("matrix.txt", "r") row = 0 for line in myFile: line = line.rstrip() nums = line,split(" ") dim = len(nums) for col in range(dim): matrix[row][col] = int(nums(col))←ここでエラーが出てしまいました   row = row+1 myFile.close() sumMatrix = [[0 for j in range(dim)] for i in range(dim)] for m in range(dim): for n in range(dim): mySum = 0 for p in range(m+1): for q in range(n+1): mySum = mySum = matrix[p][q] sumMatrix[m][n] = mySum for i in range(dim): for j in range(dim): print sumMatrix[i][j], 8行目のエラーを解消させたいのと、このプログラムで配列が大きいものになると、とても遅くなってしまうようなので、もっと早いものにしたいのですが... ご回答、よろしくお願いします。

  • コンストラクタやデストラクタと例外について

    対処法が「概念的に」書かれているサイトや書籍は結構あるようなのですが、具体的なコードでビシッと書かれてることや、そもそも根本的に「どういう場合に例外が発生するのか」の、帰納的な説明はなかなか見つからないので、もやもやしています。 また、「人が書いたコードを使う場合に全部読んでられないような状況」という前提が暗黙にあって書かれている文章が多いと感じます。 しかし、根本的なところが分からないともやもや感は拭えません。 1.もし仮に自分が全てのコードを把握し、「コーディングの段階で明白に消せる例外の可能性」を、あらかじめ消しておける(さすがにnewなどC++の標準的機能は使用し)とした場合は 自分自身で例外をthrowするか、メモリ不足でbad_allocになる以外にコンストラクタ(あるいはデストラクタ)でcatch出来るような例外が発生する可能性はあるのでしょうか? そして例えば以下のように書いたとします。(必要なヘッダ等は省略してあります) ///////////////////ヘッダ側//////////////////////// class A{ double d; public: A(double a=0) : d(a) {} ~A(void){} }; class B{ std::auto_ptr<A> p; A *alist[10]; public: B(void); ~B(void); }; ///////////////////こちらがソースです//////////////////////// B::B(void) try { memset(&alist,0,sizeof alist); std::auto_ptr<A> ap( new A(.8) ); p=ap; for ( int i=10;i; ) alist[--i]=new A; } catch(std::bad_alloc){ for ( int i=10;i; ) delete alist[--i]; } catch(...) { /*......*/ } B::~B(void){ try{ for ( int i=10;i; ) delete alist[--i]; }catch(...){} } こうしたとすると 2.このコードはコンストラクタ中で例外が発生した場合、コンストラクタなので「呼ばれることになった原因の場所へ自動的に例外が再度投げられる」という点を除けば、安全でしょうか? 3.そもそもコンストラクタで例外が発生した場合、呼び出し元に届くように「自動的に、あるいは手動で」投げなければ「ならない」のでしょうか? 4. 1とかぶりますが「このコードの場合に限定」していうと、catch(std::bad_alloc)の後ろに書いたように、果たしてcatch(...)は必要なのでしょうか? つまりstd::bad_alloc以外の例外が発生する可能性はありますか? 5.このコードの場合では、このようにデストラクタをtryブロックで囲う必要は事実上ないと考えて良いですか? 6.また、もしclass Aのデストラクタを見ることができないという場合は、逆に囲うべき、という意味なのでしょうか? 7.auto_ptrのかわりに通常のポインタを使う場合 ポインタの配列alistと同じように、先にNULLにしておいてからnewして、catch(std::bad_alloc)に入った場合は delete ポインタ。 例外が発生しなかった場合デストラクタのほうにも解放処理はちゃんと書く、としていれば、この場合大丈夫でしょうか?

  • 整数を引数にもつテンプレートクラスについて

    テンプレート引数に整数を使えると 聞いたので以下のようなクラスを 作りました。 template <int w, int h> class MyClass { double a[w][h]; MyClass(); }; temlate <int w, int h> void MyClass<w, h>::MyClass(void) { for(int i = 0; i < w; i++) { for(int j = 0; j < h; j++) { a[i][j] = 0; } } } ここでMyClass<2, 4> mc;などと呼び出してコンパイルすると undefined reference to `Matrix<2, 4>::Matrix()` とエラーが表示されます。 何が間違っているのでしょうか?

  • C++のプログラムのエラー原因のアドバイスお願いします。

    C++のソース内でエラーがでます。 エラー箇所は以下の関数内の最初と最後のflagに対する処理部分です。 ★マークをつけた部分が違うのかと思うのですが、 他人のプログラムなのでどこをどう直せばいいかわかりません。 処理部分ではflag[i][j]なのに宣言が★になる意味もわかりません・・・。new,deleteはこれで大丈夫なのかとか。 どなたかアドバイスお願いします。 環境:visual studio.NET, windowsXP 関数 { register int i, j; int row,col; bool **flag = new bool *[row+2];//★ for (i = 0; i < row+2; i++) flag[i] = new bool[col+2];//★ num_feature_point = 0; for (i = 0; i < row+2; i++) {  for (j = 0; j < col+2; j++) { /*/*ここからflag[i][j] = false; などの処理が数行*/*/ for (i = 0; i < row+2; i++) delete [] flag[i]; delete [] flag; }

  • プログラムの合成願い

    あらかじめ行列の数がわかっているN行*M列のエクセルデータをCSV形式にし、 読み込むプログラムを作成しました。 そのプログラムを下に示します #include <stdio.h> #include <stdlib.h> #include <string.h> /* 確保するデータ保存領域の大きさ(N行×M列) */ #define N 23 #define M 6 /* データの区切り文字*/ #define SEP_DATA',' int csv_read(char filename[], double csv[N][M]) { /* ファイルオープン*/ FILE *fp; if( (fp = fopen(filename, "r")) == NULL ) { printf(" file open error!!\n"); return -1; } /* 1行毎に読み出し*/ char line[256], *ptr; int i, j, k; i=0; while (fgets(line, 256, fp) != NULL) { printf("*%s", line); ptr = line; j=0; do{ /* line[j]から次のタブ文字までを数値に変換*/ csv[i][j] = atof(ptr); /* 次のタブ文字の位置を探す*/ ptr = strchr(ptr, SEP_DATA); /* タブ文字の次の文字を示す*/ if (ptr!=NULL) { ptr++; } j++; }while(ptr!=NULL && j<M); i++; } /* ファイルクローズ*/ fclose(fp); return 0; } int main(int argv, char *argc[]) { char filename[256]; if( argv > 1){ strcpy(filename, argc[1]); } else { printf("Please Input Filename:"); scanf("%s", filename); } /* データ保存用の領域を確保*/ double (*csvdata)[M]; csvdata = (double(*)[M])malloc(sizeof(double[M]) * N); //malloc(sizeof(*csvdata) * N); if ( csvdata == NULL ){ return -1; } int i,j; /* 配列の初期化*/ for( i=0; i<N; i++) { for( j=0; j<M; j++) { csvdata[i][j] = 0.0; } } /* CSVデータの読み込み*/ if( csv_read(filename, csvdata) < 0 ) { return -1; } /* 配列の出力*/ for( i=0; i<N; i++) { printf("%lf", csvdata[i][0]); for( j=1; j<M; j++) { printf("\t%lf", csvdata[i][j]); } printf("\n"); } free(csvdata); csvdata = NULL; return 0; } また、行列の数を計算するプログラムを作成しました。(プログラムは別途URLを書き込みます) http://www.kent-web.com/pubc/book/test/uploader/uploader.cgi?mode=downld&no=3797 これら二つのプログラムを合わせかたがわかりません。 プログラムで示していただきたいです。お願いします。 環境はC++です。

  • C#デストラクタが走る理由がわからない(初心者)

    WPF C# アプリを初めて組んでいます。 MainWindowクラスで、publicなクラス変数配列(myclass)を定義し、 MainWindowのコンストラクタ(もしくはLoadedイベント)で、上記クラス変数にインスタンスを生成しています。 そのインスタンスを、MainWindows内のコントロールイベント(Button_Click)で参照しようとするとNullとなっておりました。 MainWindowのコンストラクタ(もしくはLoadedイベント)完了後に、デストラクトが走っているようです。 どこからも参照されていなければGCが走りデストラクタされるのはわかるのですが、 この場合、MainWindowクラスのメンバにクラス変数を追加し、そこにインスタンスを生成しています。よって、MainWindow(つまりアプリが)が終了するまでインスタンスが参照されているため、 デストラクタが走らないのではないかと考えておりました。 ですが、上記の通り、MainWindowのコンストラクタ(もしくはLoadedイベント)後には、MyClassデストラクタが走ってしまいます。この辺を教えていただけないでしょうか。 また、下記のように、Clickでインスタンスを参照するにはどうすればよいでしょうか。 public partial class MainWindow : Window {     MYClass []myclass;     public MainWindow()     {         InitializeComponent();         //ファイル読み込み(記載省略)         for(i=0; i<ファイル読み込み数;i++)         {             myclass[i] = new myclass(ファイル読み込みデータ);         }     }     private void Button_Click(object sender, RoutedEventArgs e)     {         for(int i=0;i<myclass.Length;i++) ←ここに来る前にすでにMyClassのデストラクタが走っており、nullとなっている         {             data = myclass[i].data;         }     } }

専門家に質問してみよう