21_オブジェクトの構築順序

2921 ワード

0.質問:C++のクラスは複数のオブジェクトを定義できますが、オブジェクトの構造の順序はどうなりますか.
1.ローカルオブジェクトの構築順序
  • ローカルオブジェクトについては、プログラム実行フローがオブジェクトの定義文に到達したときに構築される.

  • プログラミングの説明:ローカルオブジェクトの構築順序
    #include 
    
    class Test
    {
    private:
        int num;
    public:
        Test(int i)
        {
            num = i;
    
            printf("Test(int i): %d
    ", num); } Test(const Test& obj) { num = obj.num; printf("Test(const Test& obj): %d
    ", num); } }; int main() { int i = 0; Test a1 = i; while( i<3 ) { Test a2 = ++i; } if( i<4 ) { Test a = a1; } else { Test a(100); } return 0; }

    出力結果:
    Test(int i): 0
    Test(int i): 1
    Test(int i): 2
    Test(int i): 3
    Test(const Test& obj): 0
    

    2.スタックオブジェクトの構造順序
  • スタックオブジェクトの場合、プログラム実行フローがnew文に到達したときにオブジェクトが作成され、newを使用してオブジェクトが作成されると、コンストラクション関数の呼び出しが自動的にトリガーされます.

  • プログラミングの説明:スタックオブジェクトの構築順序
    #include 
    
    class Test
    {
    private:
        int num;
    public:
        Test(int i)
        {
            num = i;
    
            printf("Test(int i): %d
    ", num); } Test(const Test& obj) { num = obj.num; printf("Test(const Test& obj) %d
    ", num); } }; int main() { int i = 0; Test* a = new Test(i); while( ++i < 10 ) { if(i % 2 ) { new Test(i); } } if( i<4 ) { new Test(*a); } else { new Test(100); } return 0; }

    出力結果:
    Test(int i): 0
    Test(int i): 1
    Test(int i): 3
    Test(int i): 5
    Test(int i): 7
    Test(int i): 9
    Test(int i): 100
    

    3.グローバルオブジェクトの構築順序
  • グローバルオブジェクトの場合、オブジェクトの構築順序は不確定であり、異なるコンパイラは異なるルールを使用して構築順序を決定する.

  • プログラミング説明:グローバルオブジェクトの構築順序Test.h
    #ifndef _TEST_H_
    #define _TEST_H_
    
    #include 
    
    class Test
    {
    public:
        Test(const char* s)
        {
            printf("%s
    ", s); } }; #endif

    t1.cpp
    #include "Test.h"
    
    Test t1("t1");
    

    t2.cpp
    #include "Test.h"
    
    Test t2("t2");
    

    t3.cpp
    #include "Test.h"
    
    Test t3("t3");
    

    main.cpp
    #include 
    #include "Test.h"
    
    Test t4("t4");
    
    int main()
    {
        Test t5("t5");
    
        return 0;
    }
    

    入力コマンド:
    g++ 3.cpp t2.cpp t1.cpp t3.cpp -o test.out
    

    出力結果:
    t4
    t2
    t1
    t3
    t5
    

    注:グローバルオブジェクトの構築順序は不確定であり、コンパイラベンダーによってグローバルオブジェクトの構築順序がカスタマイズされます.今後の開発過程では,グローバルオブジェクトの相互依存関係を避ける必要がある.
    4.まとめ
  • ローカルオブジェクトの構築順序はプログラムの実行フローに依存するため、goto文
  • の使用は極力避ける.
  • スタックオブジェクトの構造順序はnewの使用順序
  • に依存する.
  • グローバルオブジェクトの構築順序は不確定な
  • である.