クラス-構築とプロファイル実行順序の詳細

3617 ワード

1.例では、関数の実行順序を次のプログラムで説明します.
1)Stringクラスを定義し、その中の文字列を構築して解析して印刷する
2)2つのStringを含むベースクラスBaseを定義する
3)ベースクラスBaseから派生したDeriveクラスで,クラスにStringが1つ含まれる.
各クラスの関数メンバーは、実行関数名を印刷します.
struct String{
	String(const string& s = ""):str(s) 
		{cout<< "String():"<< str << endl;}
		
	String(const String& s):str(s.str) 
		{cout<< "String(const String& s):"<< str << endl;}
			
	String(String&& s):str(std::move(s.str)) 
		{cout<< "String(String&& s):"<< str << endl;}
		
	String& operator=(const String& s)
		{str = s.str;  cout<< "String& operator=(const String& s)"<< str << endl;}
	
	String& operator=(String&& s)
		{str = std::move(s.str); cout<< "String& operator=(String&& s)"<< str << endl;}
	
	~String() 	{cout<< "~String():" << str << endl;}
		
	string str;
};

//   
struct Base{
	Base(const String& _a, const String& _b):b(_b), a(_a) 
		{cout<

シナリオ1:関数では、先に構築された変数が後に解析され、関数に役割ドメインが存在する場合、役割ドメインが離れた後に役割ドメインで作成された変数が解析されます.
int main(int argc, char** argv) {
	String A("First");
	{
		String tmp("tmp");
	}
	String B("Second");
	return 0;
}


//    
String():First
String():tmp
~String():tmp
String():Second
~String():Second
~String():First

--------------------------------
Process exited after 0.09922 seconds with return value 0
ケース2:
配列では,構造は底から高へ,析出構造は高から低へ
//     
int main(int argc, char** argv) {
	String array[] = {string("first"), string("second")}
	return 0;
}

//    
String():first
String():second
~String():second
~String():first

--------------------------------
Process exited after 0.1071 seconds with return value 0

状況3:容器において、構造と析構順序は具体的な容器実現と関係がある.
int main(int argc, char** argv) {
	//          vec         ,  
	vector vec = {String("first"), String("second")};
	
	cout<< "
print vec:"; for(auto &s :vec) cout<< s.str << " "; cout<
ケース4:
式の関数の呼び出し順序はコンパイルに関連しており、必ずしも左から右へ順次呼び出されるわけではない.
int main(int argc, char** argv) {
	//        ,               
	cout<< String("first").str << "  " <

状況5:クラス構造が実行され、メンバーが定義された順序で構築された後、構造関数体を実行し、構築時に、まず構造関数体を実行し、メンバーを逆順序で破棄する.
注意:コンストラクション関数の初期値の順序は、クラス内のメンバー定義の順序を変更することはできません.また、関数パラメータの構築順序はコンパイラに関連付けられています.例では
構築順序を右から左へ
int main(int argc, char** argv) {
	Base base(String("first"), String("Second"));
	
	cout<< "    " <

シナリオ6:派生クラスの構造:ベースクラスが先に構築され、析構は派生クラスから先析構される
//    
String():third
String():Second
String():first
String(const String& s):first
String(const String& s):Second
Base()
String(const String& s):third
Derive()
~String():first
~String():Second
~String():third

    
~Derive()
~String():third
~Base()
~String():Second
~String():first

--------------------------------
Process exited after 0.1188 seconds with return value 0