11.C++-临时对象分析

首先来参考以下代码:

#include <stdio.h>
class Test {
    int mi;
public:
    Test(int i) {
        mi = i;
    }
    Test() {
        Test(0);
    }
    void print() {
        printf("mi = %d\n", mi);
    }
};

int main()
{
    Test t;
    t.print();
    return 0;
}

运行打印:

mi = 2424820

从上面代码可以看到, 定义Test t时,想通过Test()构造函数去调用Test(0),从而设置成员变量mi为0

为什么输出结果截然不同?直接调用构造函数Test(0)有什么问题?

回忆之前学的:9.C++-对象的构造函数(详解)

对象数组之手工调用构造函数那一节,我们使用构造函数来初始化数组:

Test Tarray[3]={ Test(),Test(1), Test(2)};        //初始化对象数组里的m_val值分别为0,1,2; 

可以看出,一个构造函数其实是有返回值的, 返回的是一个临时对象,然后通过返回值赋值给Tarray[]数组里.

所以上面代码,实际调用了一个临时对象,并没有设置成员变量mi,所以打印出随机值

 

继续深入临时对象

修改上面代码,添加一些打印信息:

#include <stdio.h>
class Test {
    int mi;
public:
    Test(int i) {
    printf("Test(int i)  i=%d\n",i);              //添加打印
        mi = i;
    }
    Test() {
        printf("Test()\n");           //添加打印
        printf("\nTest(0) begin\n");    //添加打印
        Test(0);
        printf("\nTest(0) end\n");      //添加打印
    }
    ~Test(){
           printf("~Test()\n");       //添加打印
       }
void print() { printf("mi = %d\n", mi); } }; int main() { Test t;
t.print();
return 0; }

运行打印:

Test()

Test(0) begin
Test(int i)  i=0
~Test()
Test(0) end

mi = 10455683
~Test()

从打印结果可以看到,在运行Test()时,调用了:

Test(0) begin
Test(int i)  i=0
~Test()
Test(0) end

从上面看出:

Test(0)生成的临时对象,在运行下一条语句printf("\nTest(0) end\n");时,便调用~Test()析构函数注销了.

 

除此这外,当函数的参数是某个对象,而不是引用对象,也会出现临时对象的产生.

比如: 

void func(Test t);    //不是Test& t

 

也就是说:

  • 直接调用构造函数产生一个临时对象
  • 临时对象的生命周期只有一条语句的时间
  • 临时对象的作用域只在一条语句中

 

总结

在C++中,我们应该尽量减少临时对象的产生,因为从程序效率角度上看,创建临时对象和消除临时对象也需要耗费时间的

 

posted @ 2018-03-16 21:43  诺谦  阅读(494)  评论(0编辑  收藏  举报