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

    好多bug由对象构造造成--------对象的构造与构造函数有关系

    1. 对象的构造顺序

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

    (1)对于局部对象:当程序执行流到达对象的定义语句进行构造。   对象定义--->构造---->调用构造函数

     1 #include<stdio.h>
     2 
     3 class Test
     4 {
     5 private:
     6     int mi;
     7 public:
     8     Test(int i)   //构造函数
     9     {
    10         mi = i;
    11         printf("Test(int i) : %d
    ",mi);
    12     }
    13     Test(const Test& obj)    //拷贝构造函数
    14     {
    15         mi = obj.mi;
    16         printf("Test(const Test& obj) : %d
    ", mi);
    17     }
    18 
    19     /*
    20     int getMi()
    21     {
    22         return mi;
    23     }
    24     */
    25 };
    26 
    27 int main()
    28 {
    29     int i = 0;
    30     Test a1 = i;        // 对象构造    Test(int i) :0
    31 
    32     while (i < 3)
    33     {
    34         Test a2 = ++i;   //对象的定义,那么就有对象构造3次      Test(int i) :1,2,3
    35     }
    36 
    37     if (i < 4)
    38     {
    39         Test a = a1;   //对象的定义,那么就有对象拷贝构造      Test(const Test& obj) : 0
    40     }
    41     else
    42     {
    43         Test a(100);
    44     }
    45 
    46     /*
    47 goto End;  不能非法改变程序的执行流
    48 
    49             Test a(100);               //a没有构造,初始化,后面不能使用
    50 End:
    51             printf("a.mi=%d
    ",a.getMi());   //没有初始化对象,没有调用构造函数,有的编译器会输出随机值
    52 
    53     */
    54     return 0;
    55 }

    (2)对于堆对象

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

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

     1 #include<stdio.h>
     2 
     3 //堆对象的构造顺序    Test* a1 = new Test(i);  
     4 
     5 class Test
     6 {
     7 private:
     8     int mi;
     9 public:
    10     Test(int i)    //构造函数
    11     {
    12         mi = i;
    13         printf("Test(int i) : %d
    ", mi);
    14     }
    15     Test(const Test& obj)    //拷贝构造函数
    16     {
    17         mi = obj.mi;
    18         printf("Test(const Test& obj) : %d
    ", mi);
    19     }
    20 
    21 };
    22 
    23 int main()
    24 {
    25     int i = 0;
    26     Test* a1 = new Test(i);                 //Test(int i) : 0
    27 
    28     while (++i < 10)
    29         if (i % 2)
    30             new Test(i);                    //Test(int i) : 1,3,5,7,9
    31 
    32     if (i < 4)
    33         new Test(*a1);                    
    34 
    35     else
    36         new Test(100);                      //Test(int i) :100
    37 
    38     return 0;
    39 }

    (3)对于全局对象

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

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

    //test.h

    复制代码
    #ifndef _TEST_H_
    #define _TEST_H_
    #include<stdio.h>
     
    class Test
    {
    public:
        Test(const char* s)
        {
            printf("%s
    ", s);
        }
    }; 
    #endif
    复制代码

    //t1.cpp

    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"); //全局变量  他的构造在main()之前
     
    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)全局对象构造顺序是不确定的



  • 相关阅读:
    编辑器 --- Visual Studio Code 英文界面转换成中文(简体)
    CSS3 -- column 实现瀑布流布局
    CSS3 -- 边框圆角
    CSS3 -- 弹性盒
    自适应布局要素
    Vue -- 基础知识
    Vue -- element-ui el-table 的合计在第一行显示并可点击
    如何在网页标题栏title加入logo(icon)图标?
    linux下暴力破解工具hydra【转】
    linux 服务简介
  • 原文地址:https://www.cnblogs.com/liuyueyue/p/13372577.html
Copyright © 2011-2022 走看看