第23课 神秘的临时变量

本文内容取自于对狄泰学院 唐佐林老师 C++深度解析 课程的学习总结

有趣的问题

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

在这里插入图片描述
运行结果
在这里插入图片描述

从实验结果可以看出,mi的值为一个随机数


发生了什么

程序意图:
  • 在 Test() 中以 0 作为参数调用 Test(int i)
  • 将成员变量 mi 的初始值设置为 0
运行结果:
  • 成员变量 mi 的值为随机值


思考

构造函数 是一个特殊的函数
  • 是否可以 直接调用 ?
  • 是否可以在 构造函数中调用构造函数?
  • 直接调用构造函数的行为是什么?


答案

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

编程实验

解决方案

定义一个私有成员函数init()来初始化私有变量 mi

#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\n", mi);
    }
};


int main()
{
    Test t;
    
    t.print();

    return 0;
}

运行结果
在这里插入图片描述



编译器的行为

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

编程实验

神秘的临时对象
#include <stdio.h>

class Test
{
    int mi;
public:
    Test(int i)
    {
        printf("Test(int i) : %d\n", i);
        mi = i;
    }
    Test(const Test& t)
    {
        printf("Test(const Test& t) : %d\n", t.mi);
        mi = t.mi;
    }
    Test()
    {
        printf("Test()\n");
        mi = 0;
    }
    int print()
    {
        printf("mi = %d\n", mi);
    }
    ~Test()
    {
        printf("~Test()\n");
    }
};

Test func()
{
    return Test(20);
}

int main()
{
    Test t = Test(10); // ==> Test t = 10;
    Test tt = func();  // ==> Test tt = Test(20); ==> Test tt = 20;
    
    t.print();
    tt.print();
    
    return 0;
}

运行结果:
在这里插入图片描述

经过编译器的优化,Test t = Test(10); 等价于 Test t = 10;
                                 Test tt = func(); // ==> Test tt = Test(20); ==> Test tt = 20;
                                  避免了临时对象的产生




小结

  • 直接调用构造函数将产生 一个临时对象
  • 临时对象是 性能的瓶颈,也是 来源之一
  • 现代 C++ 编译器会尽力 避开临时对象
  • 实际工程开发中需要人为的 避开临时对象
发布了42 篇原创文章 · 获赞 0 · 访问量 981

猜你喜欢

转载自blog.csdn.net/lzg2011/article/details/104392773