C++ コンストラクターの初期化リストを理解するための 1 つの記事

問題の紹介

以下のコードを読んでください。

class Time
{
    
    
public:
	Time(int hour, int min, int sec)
	{
    
    
		_hour = hour;
		_min = min;
		_sec = sec;
	}
private:
	int _hour;
	int _min;
	int _sec;
};

オブジェクトをインスタンス化した後、オブジェクトは自動的にコンストラクターを呼び出して自身の値を初期化し、初期化作業を完了します。ただし、それをメンバー変数の初期化とは言えません初期化は一度しかできませんが、「初期化」は関数本体内で動作するため、正確には複数回代入することができます。, したがって、関数本体の代入を初期化とみなすのは偏っています。
したがって、初期化子リストの導入です

1 初期化リスト

構文: コロンで始まり、その後にデータ メンバーのカンマ区切りのリストが続き、各「メンバー変数」の後に括弧で囲まれた初期値または式が続きます。

具体的な形式は次のとおりです。

class Time
{
    
    
public:
	Time(int hour, int min, int sec)
		: _hour(hour)
		, _min(min)
		, _sec(sec)
	{
    
    }


private:
	int _hour;
	int _min;
	int _sec;
};

2 注意事項

オブジェクトが初期化されると、初期化リストに従ってメンバー変数が初期化され (カスタム型がある場合は、対応するデフォルトのコンストラクターが呼び出されます)、関数本体の内容が実行されます。C++ は、初期化リストに基づいてメンバー変数を初期化する方法を認識しています。初期化リストが表示されない場合、関数はデフォルトで対応する初期化リストを生成します。

  1. 各メンバー変数は、初期化リストに 1 回だけ出現できます (初期化は 1 回だけ出現できます)。
  2. クラスには参照メンバー変数、const メンバー変数、およびカスタム型メンバー (クラスにデフォルトのコンストラクターがない場合) が含まれており、これらを初期化のために初期化リストに配置する必要があります。
  3. クラス内でメンバー変数が宣言される順序は、初期化リスト内の順序に関係なく、初期化リスト内で初期化される順序になります。

1~3

  1. 初期化子リストの各メンバー変数しかできない1 回だけ発生します (初期化は 1 回だけ発生します)。
  2. クラスに含まれるもの参照メンバー変数、const メンバー変数、カスタム型メンバー (およびクラスにデフォルトのコンストラクターがない場合)、初期化子リストに配置して初期化する必要があります。

カスタム型を初期化する場合は、まずその型のデフォルト コンストラクターがあることを確認する必要があります (デフォルト コンストラクターが何であるかに注意してください)。そうでない場合は、現在のクラスに対応するコンストラクターがないため、エラーが報告されますコンストラクターを指定すると、コンパイラーはクラス関数のデフォルトのコンストラクターを呼び出して実行します。コードは以下のように表示されます。

カスタムタイプの場合

class Date 
{
    
    
public:

	// 重点在构造函数,其他不是重点
	// 全缺省才是默认构造函数
	//Date(int year=0, int month=0, int day=0)
	//{
    
    
	//	_year = year;
	//	_month = month;
	//	_day = day;
	//}

	Date&  operator=(const Date& d1)
	{
    
    
		_year = d1._year;
		_month = d1._month;
		_day = d1._day;
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};
class Time
{
    
    
public:
	Time(int hour=0, int min=0, int sec=0)
		: _hour(hour)
		, _min(min)
		, _sec(sec)
	{
    
    
	//在函数体初始化,比较麻烦,必须保证存在默认构造z函数
		Date t1;
		_d = t1;
	}


private:
	int _hour;
	int _min;
	int _sec;
	Date _d;
};


int main()
{
    
    
	Time t(6, 30, 30);
	return 0;
}

ここに画像の説明を挿入

Date クラスのデフォルトのコンストラクターが表示されない場合、コンパイラーはランダムな値である _d の値を初期化しません。逆に、初期化リストに初期化作業を記述しておけば、Date クラスにデフォルトのコンストラクタが表示されていなくても、コンパイラは _d のカスタム型を 0 に初期化します。

class Date
{
    
    
public:
	Date& operator=(const Date& d1)
	{
    
    
		_year = d1._year;
		_month = d1._month;
		_day = d1._day;
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};

class Time
{
    
    
public:
	Time(int hour = 0, int min = 0, int sec = 0)
		: _hour(hour)
		, _min(min)
		, _sec(sec)
		,_d()
	{
    
    
	}

private:
	int _hour;
	int _min;
	int _sec;
	Date _d;
};


int main()
{
    
    
	Time t(6, 30, 30);
	return 0;
}

ここに画像の説明を挿入


const 型の場合、
const 変更されたメンバー変数は定数ですが、定数は変更できないため、関数本体で代入できません。ただし、リスト内で初期化することも、C++11 の機能を使用して宣言時に値を割り当てることもできます。

ここに画像の説明を挿入


参照型:
参照型の場合、参照は定義時に初期化する必要があり、再割り当てできないため、初期化リストにも記述する必要があります。

ここに画像の説明を挿入

こちらのブログで詳しく解説していますので、ぜひご参照ください。


  1. クラス内でメンバー変数が宣言される順序は、初期化リスト内の順序に関係なく、初期化リスト内で初期化される順序になります。

おすすめ

転載: blog.csdn.net/weixin_45153969/article/details/132686616