13 对象的构造顺序

1 问题

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

2 对象的构造顺序

  • 对于局部对象

    • 当程序执行流到达对象的定义语句时进行构造
  • 示例:局部对象的构造顺序

    • Demo

      #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 main()
      {
          int i = 0;
          Test a1 = i;  //局部对象
              
          while( i < 3 )
          {
              Test a2 = ++i;  //局部对象
          }
              
          if( i < 4 )
          {
              Test a = a1;  //局部对象
          }
          else
          {
              Test a(100);  //局部对象
          }
      
          return 0;
      }
      
    • 编译运行

      Test(int i): 0
      Test(int i): 1
      Test(int i): 2
      Test(int i): 3
      Test(const Test& obj): 0
      
  • 对于堆对象

    • 当程序执行流到达 new 语句时创建对象
    • 使用 new 创建对象将自动触发构造函数的调用
  • 示例:堆对象的构造顺序

    • Demo

      #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 = new Test(i);  //堆对象:Test(int i): 0
              
          while( ++i < 10 )
              if( i % 2 )
                  new Test(i);  //堆对象:Test(int i): 1, 3, 5, 7, 9
              
          if( i < 4 )
              new Test(*a1);
          else
              new Test(100);  //堆对象:Test(int i): 100
              
          return 0;
      }
      
    • 编译运行

      Test(int i): 0
      Test(int i): 1
      Test(int i): 3
      Test(int i): 5
      Test(int i): 7
      Test(int i): 9
      Test(int i): 100
      
  • 对于全局对象

    • 对象的构造顺序是不确定的
    • 不同的编译器使用不同的规则确定构造顺序
    • => 尽量不要使用全局对象
  • 示例:全局对象的构造顺序

    • Demo

      //test.h
      #ifndef _TEST_H_
      #define _TEST_H_
      
      #include <stdio.h>
      
      class Test
      {
      public:
          Test(const char* s)
          {
              printf("%s\n", s);
          }
      };
      
      #endif
      
      
      //test.cpp
      #include "test.h"
      
      Test t4("t4");
      
      int main()
      {
          Test t5("t5");
      }
      
      
      //t1.cpp
      #include "test.h"
      
      Test t1("t1");
      
      
      //t2.cpp
      #include "test.h"
      
      Test t2("t2");
      
      
      //t3.cpp
      #include "test.h"
      
      Test t3("t3");
      
    • g++ 编译运行:g++ test.cpp t1.cpp t2.cpp t3.cpp -o test.out

      t3
      t1
      t2
      t4
      t5
      
    • VS 编译运行

      t4
      t2
      t1
      t3
      t5
      
posted @ 2020-09-23 12:30  nxgy  阅读(143)  评论(0编辑  收藏  举报