chenke1731

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的使用顺序

全局对象的构造顺序是不确定的

相关文章: