• ベストアンサー

C++のクラスの利用宣言について

Borland C++ 5.5.1 for Win32 を使って開発をしています。 クラスの宣言方法について悩んでいます。 状況は次のような感じです。 1.コンストラクタに引数を必ず指定しなければならない クラスが存在。(クラス hoge(string) ) 2.「1.」のクラスを呼び出す ------------------------------- 1: switch (flg) 2:  case 0: 3:   hoge hg("test"); 4:   hg.method1(); 5:   break; 6: } ------------------------------- 上記ソースをコンパイル。すると、 行3 case でローカル変数の初期化がとばされた というエラーになります。 しかたがないので以下のように ソースを修正 ------------------------------- 1: hoge hg; 2: 3: switch (flg) 4:  case 0: 5:   hg("test"); 6:   hg.method1(); 7:   break; 8: } ------------------------------- すると、 行1 hoge::hoge() に一致するものが見つからない というエラーになります。 デフォルトコンストラクタを無効にしているので 仕方ないのかと思い、さらに次のようにしてみました。 ------------------------------- 1: hoge *hg; 2: 3: switch (flg) 4:  case 0: 5:   *hg = hoge("test"); 6:   hg->method1(); 7:   break; 8: } ------------------------------- これで、コンパイルは無事通るようなのですが、 実行時にアプリケーションエラーとなってしまいます。 なにやら、クラスの宣言の仕方が間違って いるような気がするのですが、 一般的にどのように宣言するのかわかりません。 どなたか、教えてください。

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

  • ベストアンサー
  • MrBan
  • ベストアンサー率53% (331/615)
回答No.4

こんなことがしたいのでしょうか? try {  hoge* fg = NULL;  switch (flg)   case 0:    hg = new hoge("test");    hg.method1(); delete hg;    break;  } } catch(std::bad_alloc& x) {  std::cerr << x.what(); } # std::auto_ptr を使った方がいいかも。

haniue
質問者

お礼

うはっ ずばりな回答ありがとうございます。 思い通りに動作しています。 C++ で new ってできるんですね(汗 No.3 で pchan0022000 さんが回答してくださった内容は 実はわたしもやってみました。 すると、なぜかアプリケーションエラーとなってしまっていました。 (method1の中でポインタ等を使いまくっている模様) 想像ですが、No.3 の方法では hoge の実態が 実はなくなってしまっているのではないかと 思っています。 MrBan さんの方法だと、 hoge の実態が 確保?されて問題なく使えるのではないかと想像 したりして。 あと、std::auto_ptr は非常に参考になりました。 みなさん ほんとうにありがとうございました。

その他の回答 (5)

noname#16581
noname#16581
回答No.6

こういうことですか?

参考URL:
http://oshiete1.goo.ne.jp/kotaeru.php3?q=1789919
  • MrBan
  • ベストアンサー率53% (331/615)
回答No.5

#4です。 ごめんなさい。以下のように訂正。    hg.method1();     ↓    hg->method1();

回答No.3

C言語最近使ってないんですが、私がわかる範囲でアドバイスを。 >ただ、クラスの宣言という意味では、 >hoge hg("") >のような宣言ではなく、「型」として宣言し、 >あとでインスタンス化した物をその型へ >代入するというような宣言の仕方というのが >ないものかと思っています。 というのであれば引数なしコンストラクタを作って、operator =をオーバーロードする事で近いものができると思います。 あと質問文の3つ目を以下のようにすると通るような。 ------------------------------- 1: hoge *lpHoge; 2: 3: switch (flg) 4:  case 0: 5:   lpHoge = &(hoge hg("test")); 6:   lpHoge->method1(); 7:   break; 8: } ------------------------------- &(hoge hg("test"))の部分はちょっと自信ないけど(;・∀・) *hg = hoge("test"); だとhgポインタの実体にhogeオブジェクトを代入みたいな感じになってる気がする。

参考URL:
http://wisdom.sakura.ne.jp/programming/cpp/cpp27.html
回答No.2

コンパイラが今ないのでアドバイスだけ。 スコープの問題だとするとCASE内を{}でくくってみると通ったりしませんか? ------------------------------- 1: switch (flg) { 2:  case 0: 3:   {hoge hg("test"); 4:   hg.method1();} 5:   break; 6: } ------------------------------- ダメなら引数のないコンストラクタを作るという方法はとれないのでしょうか? それか質問文の2番目のソースで hoge hg(""); と宣言するようにしてみるとかどうでしょう。

haniue
質問者

補足

回答ありがとうございます。 MrBan さん、pchan0022000 さんの指摘どおり、 スコープによる問題みたいです。 指摘してくださったように修正したところ 問題なく動作しました。 ただ、クラスの宣言という意味では、 hoge hg("") のような宣言ではなく、「型」として宣言し、 あとでインスタンス化した物をその型へ 代入するというような宣言の仕方というのが ないものかと思っています。 なにやら、説明しにくいのですが(^_^;ヾ

  • MrBan
  • ベストアンサー率53% (331/615)
回答No.1

一般的かどうかは分かりませんが、提示コードを見る限り、 こんな感じでは。 switch (flg)  case 0:   {    hoge hg("test");    hg.method1();   }   break;  }

関連するQ&A

  • C++変数宣言時のコンストラクタについて

    Java開発をこれまでやってきたのですが、 C++を学ぼうとしています。 C++では下記のように宣言した場合hogeは インスタンスになり、Hogeクラスのコンストラクタが呼ばれるようなのですが、 Hoge hoge; Hogeクラスのコンストラクタが下記のような引数を持つものしか定義されていなかった場合は どの様な振る舞いをするのでしょうか? Hoge(int num); Javaでは引数の有るコンストラクタしか宣言しなかった場合はデフォルトコンストラクタは 作られなかったと思うのですが、c++では引数のないデフォルトコンストラクタができてるのでしょうか? また、デフォルトコンストラクタが出来ていなかった場合、 Hoge hoge; というようにプリミティブ型のような変数宣言の仕方で引数有りのコンストラクタを呼ぶことは出来るのでしょうか?

  • C++のtemplateクラス前方宣言について教えてください

    C++で、以下のようなコードを書いたのですがコンパイルが通りません。 どのようにコードを修正すればコンパイルを通すことができるでしょうか??教えてください。 template <class _T> class Test; // 上をclass Test<_T>にしてもコンパイルは通りません void main() {   Test<int> hoge; } template <class _T> class Test { public:   _T val;   Test():val(0){}; }; /*! エラー内容: 前方宣言class Test;の場合 'hoge'が未定義のclass'Test<_T>'で使用しています。   with   {     _T=int   } 前方宣言class Test<_T>;の場合 構文エラー:';'が'<'の前にありません。 構文エラー:'<' 'hoge'が未定義のclass 'Test<_T>'で使用しています。 */ 開発環境: VisualStudio2005 AcademicEdition WindowsXP Professional メモリ:2048MB CPU:Core2Duo 1.33GHz よろしくお願いします。

  • クラス宣言とアクセス制御

    お世話になります。 独学でJavaの学習を始めました。 (仕事で必要になったためです) Java のソースファイル名は、main メソッドを宣言するクラスの クラス名と一致させなければならないようですが、これは そのクラスを public をつけて宣言したときに限るのでしょうか? 以下のソースを「hello.java」という名前で保存し、コンパイルすると エラーが出ますが、「public」を削除して再びコンパイルすると、 コンパイルが通り、「test.class」が生成されます。 ********** public class test { public static void main (String args[]) { System.out.println("Hello World"); } } ********** 同一パッケージ外からクラスを参照する場合、クラス名とソースファイル名を 一致させてあげないとクラスを見つけられない、ということなのでしょうか? とんちんかんな認識でしたら申し訳ありませんが、 ご教授頂ける方、宜しくお願い致します。 また、実際に Java を使って開発されている方にお伺いしたいのですが、 現場では main メソッドを宣言するクラスのクラス名と、ソースファイルの ファイル名を一致させる、ということは常識というか、暗黙の了解みたいな ものなのでしょうか? (もちろんプロジェクト毎のコーディング規約によると思うのですが…)

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

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

  • C++で、クラスの受け渡しを行いたい

    C++を現在勉強中です。 java は少しだけわかるのですが、 以下のjavaのコードをC++で実現する方法が わかりません。 ------------------------------------------- class test2 { private test2() { } public test2(String hoge) { } } class test1 { private void method1(test2 t2) { } public static void main(String[] args) { test1 t1 = new test1(); } } ------------------------------------------- ようは、test2クラスのデフォルトコンストラクタを不可視にしておきながら、呼び出し側でどのように定義すればよいのかがわかりません。 どなたか回答お願いします。

  • C++ のクラスの定義

    C++の初心者です。 C++のことでお聞きしたいことがあります。 namespace test1{ class A { friend class B; protected: int a; }; } とtest1の下にAクラスを作り namespace test2{ class B { public: test1::A A1; }; } と別のnamespaceにBというクラスを作り、 A1というAのインスタンスを持ちたいのです。 しかし、Aというクラスを先に宣言しているので Bというクラスが解らないらしく friendがうまく働きません。 friend class test2::B としても test2がまだ宣言されていないので、 ????とコンパイルエラーが出ます。 先にtest2::B を宣言してしまうと、 今度はtest1::Aが解らずに エラーが出てしまいます。 こんな場合はどのように書けばよろしいのでしょうか? 環境はwindows2000でVC++ 6.0です。 どうか宜しくお願いいたします。

  • クラスの変換について

    C#のクラスの変換についてお尋ねします。 switch文を使ってstring型で受けた値を int型に変換したいのですが、 下記コードの ” Convert.ToInt32(bloodType) ” のところでエラーになります。 どうすればint型に変換できるでしょうか? どなたか宜しくお願い致します。 string bloodType = ""; switch(bloodType) { case "A型": bloodType = "1"; break; case "B型": bloodType = "2"; break; case "O型": bloodType = "3"; break; case "AB型": bloodType = "4"; break; } int bloodTypeId = Convert.ToInt32(bloodType);

  • テンプレートクラス内のテンプレートクラス(インナークラス)のメソッドを実装ファイルで定義したい

    現在、ヘッダファイル内で下記のようなクラスを宣言・定義しています。 // test.h template < typename T1 > struct A {   template < typename T2 > struct B   {     B( A const& arg ) { ... }   }; }; テンプレートクラスが入れ子になっていて、Bのコンストラクタが引数としてAを取っています。 しかし現状ではコンパイルがとんでもなく遅くなってしまうので、 Bのコンストラクタは宣言のみとし、別途実装ファイル(test.cpp)に定義を書きたいと思っています。 ところがメソッドのシグネチャをどう書けばよいのか分からなくなってしまいました。 苦し紛れに // test.cpp template < typename T1, typename T2 > A<T1>::B<T2>::B( A<T1> const& arg ) { ... } などと書いてみましたが、違うようです。 解決方法はありますでしょうか? 環境はVC7.1かVC8でコンパイルできればよいです。 よろしくお願いいたします。

  • お互いをメンバに持つようなクラスの宣言

    同じヘッダファイル内で class CHoge { CPiyo piyo; //この段階ではCPiyoがわからない }; class CPiyo { CHoge hoge; //こっちを先にしてもCHogeがわからない }; といったようにお互いのオブジェクトをメンバに持つようなクラスを宣言したいのですが、CHogeの宣言を解釈する段階ではCPiyoが宣言されていないので、エラーになります。 そもそも、こういうことってできないのでしょうか?

  • 宣言していないクラス

    畏れ入ります。 例外処理の勉強をしています。 例1の場合は class CarException extends Exception{ } とクラスを定義してから if(g<0){ //例外の条件です CarException e = new CarException(); throw e; としていました。 しかしふと、ほかの例題を見てこのように変えてみました /*クラス宣言削除/ if(g<0){ throw new CarException(); } これでもまったく同じ結果でした。 わからないのは、なぜこの場合には CarExceptionクラスの定義がないのに ”シンボルが解決できません” のコンパイルエラーにならないのでしょうか? newがついているから・・・というのはわかるんですが・・・ 初歩的な質問です、すみません

    • ベストアンサー
    • Java

専門家に質問してみよう