• ベストアンサー

クラスメンバをnewで宣言できますか?

こんにちは。 教えていただきたいのですが、クラスメンバ(変数)を動的に確保することは できるのでしょうか?(一応やってみたのですが、エラーになってしまいました。) それから、Newでの二次元配列の確保は、どうやったらよいのでしょうか? ヘルプでもうまく探せません。 よろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • Fooky
  • ベストアンサー率71% (59/82)
回答No.1

ポインタをクラスメンバにしておいて、 newが返すポインタをそこに入れる、 というのでだめですか? class Integers {  public:   Integers() : ip(0) { }   ~Integers() { if( ip != 0 ) delete[] ip; }   allocate(int n){ ip = new int[n]; }  private:   int *ip; }; 2次元配列の確保は、こんな感じでどうでしょう? int (*twodim)[CNUM]  = reinterpret_cast<int (*)[CNUM]>(new int [CNUM * RNUM]); CNUMとRNUMは列数、行数を表す定数です。 CNUM*RNUM個のintを確保して、 CNUM個のintをひとまとめにして指すポインタに castして代入しています。 これで、twodim[1]は2行目のint配列の先頭を指すポインタになるので、 twodim[1][2]で、2行目の第3列目の要素を指します。

akika0215
質問者

お礼

ご回答ありがとうございました。 教えて頂いたように、ポインタをメンバにすることで 対応できました。 二次元配列のほうも、いけそうです。 本当にありがとうございました。 またよろしくお願いいたします。 ※昨日のうちにお礼を書き込みしたのですが、  うまく送信できていなかったみたいです。  遅くなってすみません。

その他の回答 (2)

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.3

> 動的確保ですが、クラス宣言の中に > int *p = new int; > を書き込んだだけです。  クラス宣言はあくまで「型情報の定義」であって、インスタンス(強いて言うならクラス型変数)が作成されるわけではありません。  従ってakika0215さんの記述はエラーとなったわけです。  (変数領域が確保されないのだから、newの結果を受け取れないのは当然ですよね) > ポインタをメンバにして参照することで、回避できたのですが、 > 他にも良い方法がありましたら教えて下さい。  動的に確保するのであれば、ポインタ型メンバを持つのが手っ取り早くてよいと思いますよ。  ただ、この動的確保を行うのがメインとなるクラスでないのであれば、動的確保とその領域へのアクセスを行うためだけのクラスを書いて、そのオブジェクトをメンバに持つようにするとよいかと思います。

akika0215
質問者

お礼

再度ご回答いただきましてありがとうございます。 とても勉強になりました。 またどうぞよろしくお願いいたします。

  • leaz024
  • ベストアンサー率75% (398/526)
回答No.2

∇動的確保について(補足要求)  どのようなコードを書いたらエラーになったのでしょう? ∇二次元配列の確保について   const int col = 10;   int (*p)[col];   //「要素をcol個持つint型の配列」への「ポインタp」の宣言   int row;   cin >> row;   p = new int[row][col];   for (int ir = 0; ir < row; ir++) {     for (int ic = 0; ic < col; ic++) {       p[ir][ic] = ir * col + ic;       cout << p[ir][ic] << ends;     }     cout << endl;   }   delete [ ] p;  これではダメですか? ※1次元以外の次元は定数にする必要があります。 (ブラウザ上で見やすくするため、全角spaceを入れています。コピペする場合、注意して下さい。)

akika0215
質問者

補足

こんにちは。ご回答ありがとうございます。 動的確保ですが、クラス宣言の中に int *p = new int; を書き込んだだけです。 想像がつかなかったので、ただ単純にやってしまいました。 ポインタをメンバにして参照することで、回避できたのですが、 他にも良い方法がありましたら教えて下さい。

関連するQ&A

  • クラスのメンバ変数のnew

    こんにちは。 クラスのメンバ変数の動的割り当てで困っていることがあります。 コンストラクタ内でメンバ変数に動的割り当てをするんですが、そこで例外処理をしなければならないようです。 例 class foo::foo() { try{ hoge = new int[100]; // hogeの代入処理 // } catch { delete[] hoge; hoge = NULL; } } foo::~foo() { delete[] hoge; hoge = NULL; } しかしこれだと不十分なようで、なかしかの対策をしないとメモリリークが起きてしまいそうなんですが どのようにやるんでしょうか?

  • 変数の宣言方法の相違によるエラー

    ある変数を関数内で宣言した場合、デバック時に「ハンドルされていない例外が発生しました」っていうエラーになります。でも、グローバル変数として宣言した場合には、同じエラーが発生しませんでした。今回の場合、配列を10,000,000ぐらい確保しようとしたので、メモリ領域を確保できなかったが、エラーの発生原因だと思います。メンバ変数とグローバル変数で確保できるメモリ領域にどれくらいの違いがありますか。その他にクラスのメンバ変数として宣言した場合とグローバル変数として宣言した場合でどのような違いがありますか。 わかる方が教えてください。よろしくお願いします。

  • クラスでnew宣言

    いつも御世話になっています。 クラス作成時に、 オブジェクト型(クラス型)を変数として宣言している時がある気がするのですが、ClassB classB = new ClassB(); この場合の利点は何かあるのでしょうか? 普通に考えれば、この記述を宣言することで、この宣言がされているクラス自身が、ClassBの実体を持つことになり、このクラスだけで多数のクラスの実体を利用できるようになる。 と思ったのですが。 クラスとしては、 ClassA { private ClassB classB = new ClassB(); } という場合です。 ここで、private ClassB classB;でない理由: むやみに、上記の書き方をすると、外部から書き換えられてしまう恐れがあるから、、なるべくその可能性を回避するため 宜しくお願いします。

    • ベストアンサー
    • Java
  • クラスがメンバーとしてクラスを持つ時の宣言について

    自作クラスMainClassがMyClassというクラスをメンバー変数として持つ場合、宣言時に引数をいくつか持つコンストラクタを呼び出そうとすると構文エラーとなります。 class MyClass { public: MyClass(int, int); } class MainClass { private: MyClass myclass(10,10); } このような宣言はできないのでしょうか。 引数なしのコンストラクタは呼び出せているようです。

  • クラスのメンバになってくれません!

    クラスに変数名・関数名を入れれば自動的にクラスのメンバとしてくれるはずですよね。だけど、クラスメンバにしてくれません。 なぜでしょうか? たすけてください!おねがいします!

  • クラスメンバの中で配列を利用したい

    Cで書いたプログラムをC++に移植してます。 普通の変数はクラスメンバに置き換えてしまえばよろしいのですが、 配列の場合そのままクラスメンバに置き換えたら 問題が発生します。(予想はついていたのですが…) class test{ private: int m_test[100]; }; クラスメンバを配列に設定するにはどうすればよいですか?

  • クラス内のメンバ変数について

    クラス内のメンバ変数について Javaで作成したクラスのメンバ変数なのですが、クラス内のメンバ変数名の 一覧を取得する方法を探しています。 昔、仕事でやったような気がするのですが、忘れていました。 やりたいことは、メンバ変数のString型のメンバにtrimを行いたいのですが、 一つずつ名称を指定したくなく、どのクラスでも共通処理を行いたいです。 よろしくお願いします。

    • ベストアンサー
    • Java
  • C++で、メンバもヒープに確保されていますか

    C++でどこまでヒープに確保されるのかが分からなくなる場合があります。 特に、配列がある場合や、クラスを使う場合newしてインスタンス作って使用する場合と、 そうでない場合があり、どこまでヒープ領域に確保されているのか 分からなくなってしまっています。 (開発環境 Visual Studio 2013等) Q1 クラス内の配列 class AA{ public: int x; int dat[10]; }; AA *a0 = new AA(); とする場合と AA a1; とする場合。 このとき、メンバ変数はそれぞれ、 a0->xはヒープ領域に確保 a1.xはスタック領域に確保 されるという理解で良いですか? そして、配列a0->dat[0]等 もヒープ領域に確保されていますか? Q2 クラス内にクラス class BB{ int u,v; AA aa; }; BB *b0 = new BB(); とした場合、 b0がヒープに確保されるとして、 b0->aaはヒープに確保されており、 b0->aa.xやb0->aa.dat[0]等もヒープに確保されているという ことで良いでしょうか? Q3 確認方法 変数等がヒープかスタック領域のどちらに確保されたかは どうやって見分けることができますか? アドレスの値から判断できますか? よろしくお願い致します。

  • 基本クラスポインタ = new 派生クラス[i];

    基本クラスのポインタ変数pbaseを宣言し、new演算子にて派生クラスの配列を動的に確保して、pbaseに代入した場合、delete[] pbaseは上手く動作するのでしょうか。 (Aのデストラクタは仮想関数にしてあるとしておきます) ------ex-start------ class A {}; class b:public A{}; main() {   A * pbase   pbase = new B[5];   delete[] pbase } ------ex-end------ 例えば、 class Aは12バイト class Bは20バイト である場合、配列のサイズが違うのに、delete[]でちゃんと開放されるのでしょうか。 それともnew/deleteは確保したサイズをシンボル毎に記憶しているのでしょうか。 どうもこの辺が曖昧で実装する時にあやふやになってしまいます。どなたかお知恵をお貸しくださいませ。

  • メンバ変数に関して

    現在、C++にてプログラム作成しております。 1点プログラミングを行っている中で疑問になった点があります。 アイデア・方法等があれば教えて頂けると幸いです。 現在、メンバ変数として配列を定義したプログラムを作成しております。 そのメンバ変数を同クラス内のたくさんのメソッドから呼び出して処理を行っているのですが、そのメンバ変数の配列数を固定配列数ではなく、可変な配列数にしたいと考えております。 プログラムの実行後に取得した値をメンバ変数の配列数にしたいのです。 このように、メンバ変数の配列数の可変可を実施することは可能でしょうか?