このページの内容 |
---|
組み込み型の初期化 |
クラス(構造体)のメンバの初期化 |
局所変数の初期化 |
ヒープオブジェクトの作成・開放 |
非局所変数の初期化 |
局所的な静的オブジェクト |
ありがたいスポンサー様 |
---|
組み込み型(int,doubleなど)は、すべて 0 で初期化される。つまり、int i ;は、int i = 0 ;またはint i = int() ;と同義である。
ここでいうクラスは、広義のクラスを指す。つまり、構造体も含む・・・ということ。構造体がクラスであることについては、構造体を参照のこと。
クラスのメンバ変数はコンストラクタで初期化することができる。特にメンバ変数のうちでも初期化を必要とするものがある。それは、デフォルトコンストラクタを持たないクラスのオブジェクト、const 宣言されたメンバ、リファレンスメンバである。これらのメンバ変数は、メンバ初期設定リストによって初期化されなければならない。
class MyClass{ const string str ; string str2 ; double dbl ; int i ; MyClass( bool bln = false) ; } ; // コンストラクタ MyClass::MyClass( bool bln) : str( ""), dbl( 1.0) // メンバ初期化リスト { // コンストラクタ内では、込み入った処理を。 i = ( bln ? 100 : 0) ; str2 = "hoge" ; }
メンバ初期化リストでは、メンバ変数のコピーコンストラクタが呼ばれる。str2のようなメンバ初期化リストで初期化されなかったメンバ変数は、MyClassのコンストラクタが呼ばれる前にstr2のデフォルトコンストラクタで初期化されている。つまり、str2は、空文字で初期化された後、hogehogeという文字列を代入されている。メンバ初期化リストではコピーコンストラクタ、コンストラクタ内では代入演算子が呼ばれていることに注意。
局所変数は、スコープを外れるとデストラクタが呼ばれる。
void main(){ MyClass m1 ; // デフォルトコンストラクタ // MyClass m1 = MyClass() ;と同義 MyClass m2 = 1 ; // MyClass( 1) を作成して、m2 のコピーコンストラクタで初期化 MyClass m3( 1) ; // MyClass m3 = MyClass(1) ;と同義 }
newとdeleteを使う。newして作成したオブジェクトは、明示的にdeleteしないと開放されない。
void main(){ MyClass* p1 = new MyClass ; MyClass* p2 = new MyClass[ 10] ; delete p1 ; delete[] p2 ; }
関数以外の場所で初期化された変数(グローバル変数・名前空間変数・クラス内の static 変数)は、main()関数が呼び出される前に初期化される。初期化・終了処理の順番は処理系に依存する。ただし、同じファイルに含まれる非局所オブジェクトのコンストラクタは、定義されている順番に呼ばれ、デストラクタが構築と逆順に呼ばれることが保証されている。
クラス内の static 変数の初期設定は次のように行う。
class MyClass{ static string str ; } ; string MyClass::str = "" ;
局所的な静的オブジェクトとは、関数の中で定義された static なオブジェクトである。局所的変数オブジェクトの初期化は、実行スレッドが定義部分に初めて到達したときに行われ、2回目以降は初期化は行われない。
#include <iostream> class MyClass{ MyClass(){ std::cout << "constructor was called.\n" ; } } void f( bool b){ std::cout << "in function f\n" ; if( b){ static MyClass c ; } } void main(){ f( false) ; f( true) ; f( true) ; }
出力結果は、以下のとおり。
in function f in function f constructor was called. in function f