zoukankan      html  css  js  c++  java
  • 第23课.神秘的临时对象

    1.下面程序输出什么?为什么?

    #include <stdio.h>
    
    class Test
    {
        int mi;
        
    public:
        Test(int i)
        {
            mi = i;
        }
    
        Test()
        {
            Test(0);       //直接调用了构造函数,会产生一个临时对象;Test(0)这个构造函数对这个临时对象进行初始化后。就被析构函数销毁了。所以对这个程序而言。这句话没有任何意义。才导致了,打印的随机值。
        }
        
        void print()
        {
            printf("mi = %d
    ", mi);
        }
    };
    
    int main()
    {
        Test t;
        
        t.print();
        
        return 0;
    }
    

    思考:

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

    答案:

    a.直接调用构造函数将会产生一个临时对象;
    b.临时对象的生命周期只有一条语句的时间
    c.临时对象的作用域只在一条语句中

    eg:

    #include <stdio.h>
    
    class Test
    {
        int mi;
        
        void init(int i)        //在实际工程中往往会提供一个私有的init函数来做初始设置
        {
            mi = i;
        }
        
    public:
        Test(int i)
        {
            printf("Test(int i)
    ");
            init(i);            //调用init初始函数
        }
    
        Test()
        {
            printf("Test()
    ");
            init(0);            //调用init初始函数
        }
        
        void print()
        {
            printf("mi = %d
    ", mi);
        }
        
        ~Test()
        {
            printf("~Test()
    ");
        }
    };
    
    int main()
    {
        printf("main begin
    ");
        
        /*    通过这段代码更加的说明了上述答案中所述的三项   
         */
        Test();        //Test().print; 
        Test(0);       //Test(0).print;
        
        printf("main end
    ");
        
        return 0;
    }
    

    2.编译器的行为

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

    #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(10);             //Test t(10);  等价于 Test t = Test(10);            
                                //理论上 1.生成临时对象; 2.用临时对象初始化t对象; 3.调用拷贝函数
                                //实际上Test t = Test(10); ==》(编译器把这里优化为) Test t = 10; 不会产生临时对象
                                //实际工程中推荐使用Test t = 10这种写法,不推荐使用Test t(10)
    
        Test tt = func();       //Test tt = func(); ==》Test t = Test(20);==》Test t = 20; 不会缠身临时对象
        
        t.print();
        tt.print();
                           
        return 0;
    }
    

    Test t[] = {Test(), Test(10), Test[10]};        //与上述类似
    

    3.总结

    直接的,简单的调用构造函数会生成临时对象;

    Test(10); 
    

    间接的调用构造函数则会被编译器优化,不会生成临时函数;

    Test t = Test(10);
    
    Test t[] = {Test(), Test(10), Test[20]};
  • 相关阅读:
    docker将jar打包镜像文件
    特性阻抗(转)
    关于三极管偏置电路的思考
    怎样理解阻抗匹配?(转)
    你要包火到几时呢
    Bluetooth Note
    今年过年没回家
    第二天(tomcat与web程序结构与Http协议与HttpUrlConnection)
    JavaIO操作(1)转换流
    canphp框架功能与特性介绍
  • 原文地址:https://www.cnblogs.com/huangdengtao/p/11829062.html
Copyright © 2011-2022 走看看