1. 程式人生 > >十九、物件的構造順序

十九、物件的構造順序

C++中的類可以定義多個物件,物件的構造順序是怎樣的?

1、物件的構造順序一

對於區域性物件:當程式執行流到達物件的定義語句時進行構造:物件定義->構造

#include <stdio.h>

class Test
{
private:
    int mi;
public:
    Test(int i)
    {
        mi = i;
        printf("Test(int i): %d\n", mi);
    }
    Test(const Test& obj)
    {
        mi = obj.mi;
        printf("Test(const Test& obj): %d\n", mi);
    }
    int getMi()
    {
        return mi;
    }
};

int main()
{
    int i = 0;
    Test a1 = i;    // Test(int i): 0
        
    while( i < 3 )
    {
        Test a2 = ++i; // Test(int i): 1, 2, 3
    }
        
    if( i < 4 )
    {
        Test a = a1;    // Test(const Test& obj): 0
    }
    else
    {
        Test a(100);
    }

    return 0;
}
int main()
{
    int i = 0;
    Test a1 = i;    // Test(int i): 0
        
    while( i < 3 )
    {
        Test a2 = ++i; // Test(int i): 1, 2, 3
    }
goto End:   // if 語句被跳過,物件定義被跳過,兩個物件都不會被建立
    if( i < 4 )
    {
        Test a = a1;    
    }
    else
    {
        Test a(100);
    }
End:
    return 0;
}

程式執行流和區域性物件的構造相關,非法改變程式執行流,會產生災難性錯誤

int main()
{
    int i = 0;
    Test a1 = i;    // Test(int i): 0
        
    while( i < 3 )
    {
        Test a2 = ++i; // Test(int i): 1, 2, 3
    }
goto End:   
    Test a(100);
End:
    printf("a.mi = %d\n", a.getMi());   // 報錯
    return 0;
}

2、物件的構造順序二

對於堆物件:

  • 當程式執行流到達new
    語句時建立物件
  • 使用new建立物件將自動觸發建構函式的呼叫

考慮下面程式中的物件構造順序

int i = 0;
Test* a1 = new Test(i);

while(++i < 10)
    if(i%2)
        new Test(i);
        
if(i < 4)
    new Test(*a1);
    
else
    new Test(100);

也會受到goto語句的影響

3、物件的構造順序三

對於全域性物件:

  • 物件的構造順序是不確定的
  • 不同的編譯器使用不同的規則確定構造順序
#include "test.h"

Test t4("t4");  // t4的構造在main之前構造,和程式執行流無關

int main()
{
    Test t5("t5");
}

儘量避開全域性物件的使用

4、小結

區域性物件的構造順序依賴於順序的執行流

堆物件的構造順序依賴於new的使用順序

全域性物件的構造順序是不確定的