zoukankan      html  css  js  c++  java
  • 15 临时对象

    1 问题

    • 下面的程序输出什么?为什么?

      class Test
      {
          int mi;
      public:
          Test(int i) {
              mi = i;
          }
          Test() {
              Test(0);  // 直接调用构造函数:产生一个临时对象,等价于空语句
          }
          void print() {
              printf("mi = %d
      ",mi);
          }
      };
      
      int main()
      {
          Test t;
          t.print();  // mi = -1080889604
          
          return 0;
      }
      
    • 程序分析

      • 程序的意图

        • Test() 中以 0 作为参数调用 Test(int i)
        • 将成员变量 mi 的初始值设为 0
      • 运行的结果

        • 成员变量 mi 的值为随机值
      • 哪个地方出了问题?

    • 【问题】构造函数是一个特殊的函数

      • 是否可以直接调用
      • 是否可以在构造函数中调用构造函数?
      • 直接调用构造函数的行为是什么?
    • 分析

      • 直接调用构造函数将产生一个临时对象
      • 临时对象的生命周期只有一条语句的时间
      • 临时对象的作用域只在一条语句中
      • 临时对象是 C++ 中值得警惕的灰色地带

    2 解决方案

    • Demo

      #include <stdio.h>
      
      class Test {
          int mi;
          
          void init(int i) {
              mi = i;
          }
      public:
          Test(int i) {
              init(i);
          }
          Test() {
              init(0);
          }
          void print() {
              printf("mi = %d
      ", mi);
          }
      };
      
      
      int main()
      {
          Test t;
          
          t.print();   // mi = 0
      
          return 0;
      }
      
    • 编译器的行为

      • 现代 C++ 编译器在不影响最终执行结果的前提下,会尽力减少临时对象的产生
    • 示例:临时对象

      • Demo

        #include <stdio.h>
        
        class Test
        {
            int mi;
        public:
            Test(int i) {
                printf("Test(int i) : %d
        ", i);
                mi = i;
            }
            Test(const Test& t) {
                printf("Test(const Test& t) : %d
        ", t.mi);
                mi = t.mi;
            }
            Test() {
                printf("Test()
        ");
                mi = 0;
            }
            int print() {
                printf("mi = %d
        ", mi);
            }
            ~Test() {
                printf("~Test()
        ");
            }
        };
        
        Test func()
        {
            return Test(20);  // 函数返回一个临时对象
        }
        
        int main()
        {
            Test t = Test(10); // 1.生成临时对象,调用构造函数 2.利用临时对象初始化一个对象,调用拷贝构造函数  => 编译器优化 <=> Test t = 10; => 只调用一次构造函数
            Test tt = func();  // 1.生成临时对象,调用构造函数 2.利用函数返回的临时对象初始化一个对象,调用拷贝构造函数 => 编译器优化 <=> Test tt = Test(20); <=> Test tt = 20; =>只调用一次构造函数
            
            t.print();
            tt.print();
            
            return 0;
        }
        
      • 编译运行

        Test(int i) : 10
        Test(int i) : 20
        mi = 10
        mi = 20
        ~Test()
        ~Test()
        
  • 相关阅读:
    webLogic的安装与配置总结
    hibernate 中save()、update()、saveOrUpdate()的区别?
    struts2+spring+hibernate+oracle整合,实现增删改查操作。(一)
    配置struts时web.xml中<url-pattern>*.action</url-pattern>
    java中,返回1000-10000中 能被3整除,且个位数是6的个数
    kubernetes部署Fluentd+Elasticsearch+kibana 日志收集系统
    用Docker搭建WordPress
    51建设Android版一些技术整理
    微信内置浏览器隐藏功能左上角功能选项
    vs2013修改默认的开发环境
  • 原文地址:https://www.cnblogs.com/bky-hbq/p/13720272.html
Copyright © 2011-2022 走看看