• ベストアンサー

C++の変数の初期化

C++を勉強中です。JavaやC#、JavaScriptといった言語はひととおり使えます。 C++におけるクラスHogeの変数hogeの初期化で、以下のふたつの構文では意味が違うようですが、どのように違うのでしょうか? Hoge hoge; Hoge hoge();

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

  • ベストアンサー
  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.3

前の人が言っている通りで Hoge hoge(); は関数宣言なので無理やりコンパイルを通そうとすると class Hoge{ }; void fuga(Hoge arg){ } Hoge hogeB(){ Hoge *poyo = new Hoge ; return *poyo ; } ; void piyo(void){ Hoge hogeA; fuga(hogeA); fuga(hogeB()); } こうなります。 ※これをマトモに参考にするとメモリーリークを起します。 Hoge hoge(x); とか引数をとるのであればコンストラクタのオーバーロードとして解釈可能ですが、 引数を取らないコンストラクタは定義済みなので( )を付けるとコンストラクタではなく関数と解釈されます。

hirusagari
質問者

お礼

Hoge hoge(); は関数宣言で、 Hoge hoge; は引数無しのコンストラクタ呼び出しで、 Hoge hoge(引数, ...); は引数ありのコンストラクタ呼び出しなのでしたか。 似たような構文なので Hoge hoge(); はコンストラクタ呼び出しだと 勘違いしていました。 Java等の構文に慣れている身としては少々意表を突かれる構文でした。 ありがとうございました。

その他の回答 (3)

  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.4

> Hoge hoge(引数, ...); は引数ありのコンストラクタ呼び出しなのでしたか。 引数有りのコンストラクタが定義されていればコンストラクタと解釈可能なだけで関数定義されていれば関数です。 引数つきが全てオーバーロードされたコンストラクタでは無いので誤解しませんように。 ※メソッドでもオブジェクトでも無い関数はJavaにもC#にも無いですからピンとこないかもしれませんが。

hirusagari
質問者

お礼

なるほどです。 JavaScriptやHaskellなんかもかじってるので「関数」はわかりますが、 どちらかというと関数本体のなかで関数定義ができてしまうことや、 関数やコンストラクタ呼び出しの構文と定義の構文がかぶっていることがピンとこないです……。 C++は難しいですね。ありがとうございました。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> Hoge hogeB(); > fuga(hogeB); //コンパイルエラー、conversion from `Hoge (*)()' to non-scalar type `Hoge' requested これは、hogeBが関数型であり、Hoge型に変換できないために発生しているエラーです。 > Hoge hoge();  > は質問文で述べたとおり、関数の宣言のことではありません。 それは、質問者さんが関数の宣言ではない「つもり」なだけです。コンパイラは関数の宣言だと受け取ります。

hirusagari
質問者

お礼

そうだったのですか。Hoge hoge(); は引数無しのコンストラクタを 呼んでいるのかと思ったら、全然違ったのですね。 ありがとうございました。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.1

> Hoge hoge; Hoge型のオブジェクトhogeの宣言 > Hoge hoge(); 引数を持たずHoge型を返す関数hogeの宣言

hirusagari
質問者

補足

ご回答ありがとうございます。 Hoge hoge();  は質問文で述べたとおり、関数の宣言のことではありません。 もしかしたら質問文がちょっとわかりにくかったかも知れないので サンプルコードを書きます。 以下のような違いについてご質問したいと思います。 環境はMinGW 5.1.3です。 class Hoge{ }; void fuga(Hoge arg){ } void piyo(void){ Hoge hogeA; fuga(hogeA); //OK Hoge hogeB(); fuga(hogeB); //コンパイルエラー、conversion from `Hoge (*)()' to non-scalar type `Hoge' requested }

関連するQ&A

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

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

  • C言語のグローバル変数の初期化について

    C言語において int a = 1; // 動的グローバル変数 static int b = 2; //静的グローバル変数 funcA(){ int c = 3; // 動的ローカル変数 static int d = 4; //静的グローバル変数 ・ ・ ・ } 上記のように各種変数を初期化したとします。 "c"のような動的ローカル変数であれば、funcA()が呼ばれたときに毎回初期化されますよね? では ・"d"のような静的ローカル変数は、初めてfuncA()が呼ばれたときに初期化されるのですか? ・"a","b"のyほうなグローバル変数は、どのタイミングで初期化されるのですか? 以上2点について伺いたいと思います。 ちなみに、組み込み機器むけのソフトウェアを想定しています。

  • static constメンバ変数(配列)の初期化について

    C++初心者です。 constメンバ変数の初期化について教えてください。 クラスの中に、static constメンバ変数(配列)を持ちたいのですが、 <コード1> class hoge { public : hoge(){}; virtual ~hoge(){}; static const int fuga[2] = {1, 2}; }; とすると、VC++ 2005では、 error C2059: 構文エラー : '{' error C2334: '{' の前に予期しないトークンがありました。関数の本体は無視されます というエラーが発生します。 何がいけないのでしょうか? また、下の様にするとOKでした。 <コード2> class hoge { public : hoge(){}; virtual ~hoge(){}; static const int fuga[2]; }; const int hoge::fuga[2] = {1,2}; こうすればコンパイルが通る事は分かったのですが、なぜこんな面倒な事をしないといけないのかが分かりません。 コード1では何がいけないのでしょうか? 以上、よろしくお願いします。

  • 同時に環境変数を変えることはできるのでしょうか・

    javaのプログラミングの勉強をしていて、ついでにC言語の勉強をはじめようと思ったのですが、環境変数のところでいきなりつまずいています。 javaの環境変数はきちんと設定されているのですが 新しくC言語の環境変数を通すと、以前のjavaで設定 した環境変数を消すことになってしまいます。 javaとc言語のpathの環境変数を同時に設定したまま 残すことはできないのでしょうか? どなたかお願いします!!

  • C,C++に変数の初期化と処理系について

    C,C++で変数宣言したけれども初期化しないで使った場合、何らかの値を出力してしまう場合とかエラー(core dumpなども)を出して停止する場合など処理系依存ということになると思います。また、別言語ではデフォルトでゼロ指定される場合もあります。これは自動初期化とい意味で初期化がされているものに分類されます。 処理系で初期化しないで変数を利用して適当な値を出すという風になっているとしたらその理由とかメリットというのがあるものでしょうか。core dumpで処理が停止するというのは当然であり、良心的とも言えるわけで、適当な値を出すことは危険極まりないと思うのですが。 Windowsで、分子・分母の変数を定義しないで割り算したところ、256な数値が出ました。 Linuxではcore dumpになるところだと思います。 初期化して使え、ということを徹底するべきですが、逆に初期化しないでも(すなわち変数としてどのアドレスに対応しているか不明であっても?)計算を進めてしまうメリットがどこかにあるのか?という疑問が生じます。 いかがでしょうか。そこが分かれば尚更変数を初期化して使う習慣が身に着くと思うわけですが。

  • PHPにおいて変数の初期化

    PHPで変数を初期化する際の初期化の方法について質問です。 私はPHPで変数を初期化するさい、視認しやすい様にsettype関数を用いることが おおいです。 単純に $hoge = array(); $foo = ""; $hoo = 1; とするより settype($hoge,"array"); とした方が、明確に 「ああ。この変数はこの行数で初めてでてきたんだな」 という具合に判断できるとおもっているからです。 例えばJSだと var hoge; という具合に、変数そのものの宣言を先んじておこなえますよね。 このように明確な変数宣言がわかりやすいとおもうのですが・・・・。 みなさまがたはPHPではどのように変数を初期化しますか? ご意見おきかせください。

    • 締切済み
    • PHP
  • Objective-Cクラス変数インスタンス変数

    現在iPhoneアプリを作成するために、Objective-Cの勉強をしています。しかしそこでわからないことがあり、質問させていただきました。 それは私がインスタンス変数(メンバ変数)を宣言してつかっているつもりなのですが、クラス変数の様な動きをするのです。 具体的にコードで説明します。 @implementation Main : NSObject - (void)hello{ [[Hoge alloc]init]; [[Hoge alloc]init]; } @end @implementation Hoge : NSObject NSNumber *i; - (id)init{ [super init]; NSLog(@"%d",i.intvalue); i = [NSNumber numberWithInt:123]; return self; } @end 出力結果 null 123 今手元にソースがないので正確ではないかもしれませんが、こんな感じです。hファイルにはとくになにもかいてません。 このソースの動きはmainでHogeクラスのインスタンスを二回作成することによって、initを二回呼んでいます。 疑問点は出力結果の挙動が予想外なことです。私としてはインスタンス作成時のiは初期化されていないため、 出力結果 null null になるのを期待しています。しかし二回目のinitでは前回に作成した123というデータが引き継がれています。この挙動はiはインスタンス変数ではなく、クラス変数のようにみえます。 しかしObjective-Cではクラス変数は存在しないとどっかのサイトに書いていました。 以上が質問です。なにかお気づきになった点があればごかいとういただけると幸いです。

  • クラスインスタンスとクラス型変数の配列

    C++からシフトしてきた若輩JAVAプログラマですが、微妙に理解しきれない部分があるため、お知恵をお借りしにきました。 最初にC++のサンプルを書かせていただきます。 ----- C++ ----- class Hoge {  /* 実装省略 */ } int main( void ) {  Hoge *hoge = new Hoge ;  Hoge *hoge = new Hoge[10] ; } --------------- これをJAVAで実装した場合、以下のようになると思います。 ----- JAVA ----- class Hoge {  /* 実装省略 */ } class Test {  public static void main( String[] args )  {   Hoge hoge = new Hoge() ; /* 1 */   Hoge[] hoge = new Hoge[10] ; /* 2 */  } } --------------- JAVAの場合、2ではクラスのインスタンスが確保されていないことを知りました。C++ではnewの役割が「何かをメモリ上に確保する(malloc)」という意味合いであったのに対し、JAVAの場合は考え方が違うものだということでしょうか。 そうすると、 int[] a = new int[10] ; と、 Hoge[] hoge = new Hoge[10] ; のnewは、意味が違うという認識にたどり着いてしまうのですが、そうなると『妙な』気持ちがしてしまいます。そんな面倒な言語仕様では無い気もしますし。 私の考え方が間違っている可能性が高いと思いますので、教唆していただけると助かります。 よろしくお願いします。

    • ベストアンサー
    • Java
  • C言語で変数を初期化するにはどうすればよいでしょうか。

    こんにちは。 C言語で、一度文字列を入力した変数(ポインタとか配列のことを含めてます)を再度初期化することは可能でしょうか。「初期化」という表現が合っているのか自信はないのですが、要は一度変数に入れた文字列を消去して、再利用する方法を探しています。 目標は、 1.ファイルに変数の文字列を出力する FILE *fp = fopen("file.txt","w") char *str = "text" fprintf(fp,"%s",str) ↓ 2.その変数は初期化し、初期化した変数にまた文字列を代入する *str = 初期化 *str = "text2"; ↓ 3.それをまたファイルに出力する(以下エンドレス) fprintf(fp,"%s",str) という流れにしたいのですが、2.の「初期化」がわからないので、文字列を代入すると、最初にいれた"text"のあとに"text2"がくっついてくる形になってしまい困っています。 これだとstrの容量が大きくなってしょうがないですし、ファイルに出力される文字列も重複したものになってしまうので、いったんstrに入っている文字列を消去してしまって、また新たにstrに文字列を入れようと思っているのですが可能でしょうか。 1~3の動作をほぼエンドレスでやりたいので、新たに変数を作るというやり方意外に何か良い方法があれば教えて頂けないでしょうか。どうぞ宜しくお願いします。

  • C#での変数スコープ?

    Net 2.0のC#で同一名の変数を使う場合について質問いたします。 以下のHoge1の場合には「 ローカルの変数 'x' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'x' の意味が変更されるのを避けるためです。」と怒られます。 一方、Hoge2の場合には怒られません。 Hoge2内でx=1;ではなくint x=1;と再宣言しているにもかかわらず怒られないのは、Hoge1が厳格にスコープ管理している点からみると意外に感じられます。 http://www.atmarkit.co.jp/ait/articles/0210/16/news001_5.html の記述を見ると、この記事が書かれた2002年ごろにはHoge2もNGだったような印象を受けるのですが、変化があったのでしょうか? この辺りの事情に詳しい方がおられましたらよろしく、お願い申し上げます。 class Class1 {    private void Hoge1()    {       int x;       {          int x = 2; // これはNG!。「ローカルの変数 'x' をこのスコープで宣言することはできません。これは、'親またはカレント' スコープで別の意味を持つ 'x' の意味が変更されるのを避けるためです。」と怒られる。       }    }    int x;    private static void Hoge2()    {       int x=1; //これはOK!親にぶらさげた変数が通る。    } }

専門家に質問してみよう