zoukankan      html  css  js  c++  java
  • 第21课 对象的构造顺序

    1. 对象的构造顺序

    C++中的类可以定义多个对象,那么对象构造顺序是怎样的?

    (1)对于局部对象:当程序执行流到达对象的定义语句进行构造

    (2)对于堆对象

      ①当程序执行流到达new语句创建对象

      ②使用new创建对象自动触发构造函数的调用

    (3)对于全局对象

      ①对象的构造顺序不确定的

      ②不同的编译器使用不同的规则确定构造顺序

    【实例分析】局部对象的构造顺序  21-1.cpp

    #include <stdio.h>
    
     
    
    class Test
    
    {
    
    private:
    
        int mi;
    
     
    
    public:
    
        Test(int i)
    
        {
    
            mi = i;
    
            printf("Test(int i): %d
    ", mi);
    
        }
    
     
    
        Test(const Test& obj)
    
        {
    
            mi = obj.mi;
    
            printf("Test(const Test& obj): %d
    ", mi);
    
        }
    
     
    
        ~Test()
    
        {
    
           printf("~Test(): %d
    ", mi);
    
        }
    
    };
    
     
    
    int main()
    {
    
        int i = 0;
    
        Test a1 = i;//Test(int i):0,执行到这里时构造a1
    
     
    
        while(i < 3)
    
        {
    
            //注意:a2的作用域只在这个大括号内
    
            //所以,每执行1次,构造一次a2
    
            Test a2 = ++i;//Test(int i):1、2、3
    
        }
    
     
    
        goto LabelEnd; //因跳转,所以下列的a不会被构造
    
     
    
        if (i < 4)
    
        {
    
            Test a = a1;//Test(const Test&):0。但因goto,该对象不会被构造
    
        }
    
        else
    
        {
    
            Test a(100);//不会被执行,所以不会调用Test(int i)
    
        }
    
     
    
    LabelEnd:
    
     
    
        return 0;
    
    }

    【编程实验】堆对象的构造顺序  21-2.cpp

    #include <stdio.h>
    
     
    
    class Test
    
    {
    
    private:
    
        int mi;
    
     
    
    public:
    
        Test(int i)
    
        {
    
            mi = i;
    
            printf("Test(int i): %d
    ", mi);
    
        }
    
     
    
        Test(const Test& obj)
    
        {
    
            mi = obj.mi;
    
            printf("Test(const Test& obj): %d
    ", mi);
    
        }
    
     
    
        ~Test()
    
        {
    
           //printf("~Test(): %d
    ", mi);
    
        }
    
    };
    
     
    
    int main()
    
    {
    
        int i = 0;
    
        Test* a1 = new Test(i); //Test(int i):0
    
     
    
        while(++i < 10)
    
            if (i % 2)  //i % 2 !=0
    
                new Test(i);//Test(int i):1、3、5、7、9
    
     
    
        if (i < 4)
    
        {
    
            new Test(*a1);//Test(const& Test):0
    
        }
    
        else
    
        {
    
            new Test(100);//Test(int i):100
    
        }
    
     
    
        return 0;
    
    }

    【实例分析】全局对象的构造顺序  21-3.cpp

    //test.h

    #ifndef _TEST_H_
    
    #define _TEST_H_
    
     
    
    #include<stdio.h>
    
     
    
    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 <stdio.h>
    
    #include "test.h"
    
     
    
    //注意:全局变量会先于main函数执行,因此
    
    //4个全局变量t1-t4会被先构造,再其顺序是不确定的,
    
    //要依赖于编译器。
    
     
    
    //当构造完全局对象后,会执行main函数,可以发现
    
    //t5是最后一个被构造的。
    
     
    
    Test t4("t4");//全局变量
    
     
    
    int main()
    
    {
    
        Test t5("t5");//局部变量
    
        return 0;
    
    }

    g++编译器的输出结果:

    //实验1:g++ main.cpp t1.cpp t2.cpp t3.cpp

    //t3->t2->t1->t4->t5:  从右向左

    //实验2:g++  t3.cpp t1.cpp main.cpp t2.cpp

    //t2->t4->t1->t3->t5:  从右向左

    2.小结

    (1)局部对象构造顺序依赖于程序的执行流

    (2)堆对象构造顺序依赖于new的使用顺序

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

  • 相关阅读:
    简明python_Day2_字典、集合、模块、类、编程习惯
    测试2T2
    测试2T1
    bzoj2761
    一元三次方程求根公式及韦达定理
    状压DP入门——铺砖块
    高精度模板
    测试1T3
    测试1T2
    测试1T1
  • 原文地址:https://www.cnblogs.com/hoiday/p/10091849.html
Copyright © 2011-2022 走看看