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

    问题:

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

    对象的构造顺序一:

    示例如下:

     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 main()
    21 {
    22     int i = 0;
    23     Test a1 = i;
    24         
    25     while( i < 3 )
    26     {
    27         Test a2 = ++i;
    28     }
    29         
    30     if( i < 4 )
    31     {
    32         Test a = a1;
    33     }
    34     else
    35     {
    36         Test a(100);
    37     }
    38 
    39     return 0;
    40 }

    运行结果如下:

     添加上goto语句,运行结果如下:

    引入goto使得30-37行的程序被跳过,因此a对象就不会被构造了。

    执行流和局部对象的构造息息相关。

    非法改变程序的执行流,可能引起灾难性的错误。

    示例如下:

    我们使用goto跳过了34行,在36行又调用这个a对象,这时编译器就会报错。

    g++编译器在这种情况下会报错,但是其他编译器却不一定。

    VC下的编译运行结果如下:

    可见编译器之间的行为并不一样。

    对象的构造顺序二:

    示例程序:

     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     int getMi()
    19     {
    20         return mi;
    21     }
    22 };
    23 
    24 int main()
    25 {
    26     int i = 0;
    27     Test* a1 = new Test(i); // Test(int i): 0
    28         
    29     while( ++i < 10 )
    30         if( i % 2 )
    31             new Test(i); // Test(int i): 1, 3, 5, 7, 9
    32         
    33     if( i < 4 )
    34         new Test(*a1);
    35     else
    36         new Test(100); // Test(int i): 100
    37         
    38     return 0;
    39 }

    运行结果如下:

     堆对象的创建也会受到goto语句的影响。

     对象的构造顺序三:

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

    示例:

     1 #ifndef _TEST_H_
     2 #define _TEST_H_
     3 
     4 #include <stdio.h>
     5 
     6 class Test
     7 {
     8 public:
     9     Test(const char* s)
    10     {
    11         printf("%s
    ", s);
    12     }
    13 };
    14 
    15 #endif
    1 #include "test.h"
    2 
    3 Test t1("t1");
    1 #include "test.h"
    2 
    3 Test t2("t2");
    1 #include "test.h"
    2 
    3 Test t3("t3");
    1 #include "test.h"
    2 
    3 Test t4("t4");
    4 
    5 int main()
    6 {
    7     Test t5("t5");
    8 }

    全局对象的构造一定是在main函数执行前完成的,这和程序的执行流没有关系。因为main函数执行前不存在执行流的概念。

    如果出现多个全局对象,则他们的构造顺序就不确定了。

    运行结果如下:

     VC下的编译情况如下:

    运行结果如下:

    由以上现象可以看到,全局对象的构造顺序是不确定的,不同的编译器是不一样的。

    因此,我们在开发的时候要避开全局对象之间的相互依赖。

    小结:

  • 相关阅读:
    ABP之模块分析
    AutoMapper之ABP项目中的使用介绍
    Castle Windsor常用介绍以及其在ABP项目的应用介绍
    EasyUI实战经验总结,给有需要的人
    无法发送具有此谓词类型的内容正文
    ADO.NET 新特性之SqlBulkCopy
    SVN无法Cleanup
    Mac使用操作
    Mac下的Mysql无法登陆的问题
    mac 终端 常用命令
  • 原文地址:https://www.cnblogs.com/wanmeishenghuo/p/9569537.html
Copyright © 2011-2022 走看看