C++

【C++】なにも代入していないクラス変数に値が入っている理由

投稿日:2016年9月7日 更新日:

こんにちは、C++の案件を年に1度だけ対応するプログラマーDENです。

今回は変数の初期化について。
Javaプログラマーの僕がなんで?って思った事について調べてみました。

スポンサーリンク

変数を初期化しないのに動く?

C++案件を修正していると、何も値を代入していない変数を平然と使っているソースコードを見かけます。
こんな感じです。

この変数fogeには、値が何も代入されていません。

インスタンスのない変数のメンバであるint_aを参照しています。

Javaだったらこれはコンパイルエラーになります。

ですがC++でコンパイルも通りますし、普通に動いちゃうんですよ。

不思議ですよね。
では変数fogeには何が入っているのでしょうか…?

暗黙的に呼び出されるデフォルトコンストラクタ

実は、C++では値の代入を省略すると、デフォルトコンストラクタが暗黙的に呼び出されるのです。

デフォルトコンストラクタの性質

  • 引数の指定がないコンストラクタ
  • コンストラクタが1つも定義されていなければ自動生成される

暗黙的に、引数なしのコンストラクタが呼ばれるという事なので、下記の2つのソースコードはイコールになります。

なるほど、変数の中身はかっらぽかと思っていましたが、暗黙的にインスタンスが代入されていたのでコンパイルエラーにもならずに、正常に動作していたんですね〜。

暗黙的代入を利用する際の注意点

じゃあ、引数ありのコンストラクタを使う時以外は初期値を入れる必要ないね!
って思うかもしれませんが、ちょっと待ってください。

下記のようなケースはエラーになってしまうので注意です。

基本型は暗黙的代入の対象外

下記のコードはエラーになります。

基本型は暗黙的に初期化されません。

引数なしコンストラクタがないクラスは暗黙的代入の対象外

こちらのケースもエラーになります。

基本型でもないので、デフォルトコンストラクタが呼び出せれると思いきや、このクラスはデフォルトコンストラクタがないんです。

コンストラクタが1つも実装されていなければ、デフォルトコンストラクタが自動生成されるのですが、1つでも実装されていれば生成されません。
このFogeクラスは、Foge(int param)の引数ありコンストラクタしか存在しないのです。

デフォルトコンストラクタが存在しないので、デフォルトコンストラクタを呼び出す暗黙的代入が機能しないということですね。

下記のソースコードは正常に動きます。

このコードでは、Fogeクラスにコンストラクタが何も実装されていませんので自動的にデフォルトコンストラクタ生成されます。
デフォルトコンストラクタがあれば、暗黙的代入が作動するので問題なく動くという事です。

まとめ

C++で何も値を代入していない変数は、一見空のように見えますが、暗黙的にデフォルトコンストラクタで生成されたオブジェクトが代入されているんですね。

ただし、暗黙的に値が代入されるには条件があり、一概にC++で初期化不要と言えるわけではありません。

ソースコードの可読性や、後から引数ありコンストラクタを定義したら動作しなくなるリスクを考えると、暗黙的代入に頼らず変数は初期化する癖をつけておいたほうが良さそうですね。

スポンサーリンク


-C++

執筆者:

関連記事

【C++】浮動小数点数の誤差(double→floatで値が変わる)

C++で下記の2つのメソッドに3.6fを引数に渡すと異なる結果になります。

test1は35を返し、test2は36を返します。 3. …

C++のメモリ管理【ヒープ領域とスタック領域】

こんにちは! DENです。 JavaやPHPを使っているとメモリの管理ってあまり意識しないと思います。 ですが、C++ではそうはいきません。 しっかりと理解して実装しないと、予期せぬ不具合を生んだり、 …

プロフィール

このサイトを運営しているDENです。
アングラーのフリープログラマー。 主にプログラミングと釣の話を発信しています。
プログラミングで自由になり思う存分に釣りをしまくる生活実践中。
詳しいプロフィールはこちら 
フォスターフリーランス