第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\n", 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)\n");
init(i); //调用init初始函数
}

Test()
{
printf("Test()\n");
init(0); //调用init初始函数
}

void print()
{
printf("mi = %d\n", mi);
}

~Test()
{
printf("~Test()\n");
}
};

int main()
{
printf("main begin\n");

/* 通过这段代码更加的说明了上述答案中所述的三项
*/
Test(); //Test().print;
Test(0); //Test(0).print;

printf("main end\n");

return 0;
}

2.编译器的行为

现代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(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]};

posted @ 2019-11-10 11:42  人民广场的二道贩子  阅读(161)  评论(0)    收藏  举报