思考:

构造函数是一个特殊的函数

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

答:

直接调用构造函数将产生一个临时对象

临时对象的生命周期只有一条语句的时间

临时对象的作用域只在一条语句中

临时对象是C++中值得警惕的灰色地带

#include <stdio.h>

class Test {
int mi;
public:
Test(int i)
{
mi = i;
}
Test()
{
Test(0);
// 调用Test(int i),得到了一个临时对象,生命周期只有这句话,过了之后临时对象就被析构,临时对象没有名字,作用域也只有这句话,过了之后,不能再被访问。这里的临时对象几乎就没有作用。这个0根本就没有设置到mi上
}
// 等价于
Test(){ };
void print() {
printf("mi = %d\n", mi);
}
}; int main()
{
Test t; t.print(); return 0;
} // 解决办法
// 提供一个私有的init函数,做初始设置
class Test {
int mi;
void init(int i)
{
mi = i;
}
public:
Test(int i) {
printf("Test(int i)\n");
init(i);
} Test(){
printf("Test()\n");
init(0); // 调用的普通私有函数,不会产生临时对象
}; void print() {
printf("mi = %d\n", mi);
} ~Test()
{
printf("~Test()\n");
}
}; int main()
{
printf("main begin\n"); Test(); // 直接调用构造函数,会产生一个临时对象
Test(10); // 产生临时对象 printf("main end\n") return 0;
} /*结果
main begin
Test()
~Test()
Test(int i)
~Test()
*/ int main()
{
printf("main begin\n");
Test().print(); // Test()结果是一个临时对象,是一个合法的对象,然后操作它的成员函数
Test(10); // 产生临时对象
printf("main end\n") return 0;
} /*结果
main begin
Test()
mi = 0 // 临时对象的打印
~Test()
Test(int i)
mi = 10 // 临时对象的打印
~Test()
*/

编译器的行为:现代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 = Test(10); // 1、生成一个临时对象;2、用临时对象初始化t
// ==> 调用拷贝构造函数
// 但是结果并没有打印拷贝构造函数,说明编译器没有生成临时变量
// 原因是现代编译器都会尽量减少临时变量的产生,
// 编译器将这句话等价成了 Test t(10)
// 临时变量的产生会带来性能上的问题
t.print(); Test tt = func();
tt.print(); // 会打印出20
/*
理论上应该是要调用拷贝构造函数,但是没有
编译器将这句话等价成了 ==> Test tt = Test(20) ==> Test tt = 20;
*/ return 0;
}

小结

直接调用构造函数将产生一个临时对象

临时对象是性能的瓶颈,也是BUG的来源之一

现代C++编译器会尽力避开临时对象

实际工程开发中需要认为地避开临时对象

二十一、C++中的临时对象的更多相关文章

  1. C++中的临时对象

    1,临时对象神秘在于不知不觉就请入程序当中,并且给程序带来了一定的问题: 2,下面的程序输出什么?为什么? #include <stdio.h> class Test { int mi; ...

  2. 认识C++中的临时对象temporary object 分类: C/C++ 2015-05-11 23:20 137人阅读 评论(0) 收藏

    C++中临时对象又称无名对象.临时对象主要出现在如下场景. 1.建立一个没有命名的非堆(non-heap)对象,也就是无名对象时,会产生临时对象. Integer inte= Integer(5); ...

  3. (二十一)WebGIS中鹰眼的实现思路

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 鹰眼功能是WebGIS中的一种常见功能,利用一些开源的框架实现 ...

  4. AngularJS进阶(二十一)Angularjs中scope与rootscope区别及联系

    Angularjs中scope与rootscope区别及联系 scope是html和单个controller之间的桥梁,数据绑定就靠他了.rootscope是各个controller中scope的桥梁 ...

  5. 二十一、JavaScript之访问对象属性

    一.代码如下 二.执行效果如下 <!DOCTYPE html> <html> <meta http-equiv="Content-Type" cont ...

  6. 读书笔记_Effective_C++_条款二十一:当必须返回对象时,别妄想返回其reference

    在栈空间的临时成员变量在函数生命期结束后无法传出 friend A& operator*(const A& a, const A& b) { A temp; temp.data ...

  7. 从汇编看c++中临时对象的析构时机

    http://www.cnblogs.com/chaoguo1234/archive/2013/05/12/3074425.html c++中,临时对象一旦不需要,就会调用析构函数,释放其占有的资源: ...

  8. 【编程篇】C++11系列之——临时对象分析

    /*C++中返回一个对象时的实现及传说中的右值——临时对象*/ 如下代码: /**********************************************/ class CStuden ...

  9. 与临时对象的斗争(上)ZZ

    C++ 是一门以效率见长的语言(虽然近来越来越多的人“不齿”谈及效率,我深以为不然,在某一次的程序编写中不对效率锱铢必较并不意味意味着我们就不应该追求更多的更好的做法).总之吧,相比起其它语言,程序员 ...

随机推荐

  1. 支持通配符查询的k-gram索引

    k-gram索引的通配符查询处理技术称为k-gram索引. 一个k-gram代表由k个字符组成的序列.对于词项castle来说,cas.ast.stl都是3-gram.我们用特殊的字符$来标识词项的开 ...

  2. PJzhang:kali linux安装网易云音乐、Visual Studio Code、skype

    猫宁!!! 参考链接:https://blog.csdn.net/cloudatlasm/article/details/79183583 https://code.visualstudio.com/ ...

  3. Git 深度学习填坑之旅三(分支branch、远程操作)

    0x01 分支branch依旧借用大表哥(@表元素)的图 很多时候,我们需要建立另一条分支来进行项目的独立开发,当完成后再跟主流回合进行合并这个时候就要启用分支branch功能 git branch ...

  4. 极客学院年VIP卡原价260的F码,200出售

    F码是中国最大的IT职业在线教育平台——极客学院推出的VIP时间兑换码,凭此可在极客学院官网兑换年VIP,畅享平台上所有IT技术课程. 购买请点击 http://www.bejson.com/othe ...

  5. GYM 101572I(有向图上最小环)

    逗号空格是假的,全都直接连边就行. 提供一个迪杰n次的图上最小环板子. #include <cstdio> #include <cstring> #include <io ...

  6. 51nod1244 欧拉函数之和 杜教筛

    和上一题差不多,一个是μ*I=e,一个是φ*I=Id 稍改就得到了这题的代码 (我会告诉你我一开始逆元算错了吗) #include <bits/stdc++.h> #define MAX ...

  7. hdu1166-敌兵布阵-分块

    把区间分成√n份降低复杂度. #include<bits/stdc++.h> #define inf 0x3f3f3f3f ; ; using namespace std; int t,n ...

  8. openstack安装newton版本Nova部署(三)

    一.控制节点安装部署Nova Nova 包含API(负责接收相应外部请求,支持OpenStackAPI,EC2API):cert:负责身份认证:schedule:用于云主机调度(虚拟机创建在哪台主机上 ...

  9. C#数据类型 值传递和引用传递

    /// <summary> /// 电脑类 /// </summary> public class Computer { public string Type { get; s ...

  10. filter配置多个url-pattern和排除个别servlet

    转载自:https://blog.csdn.net/hanghangde/article/details/51298221 侵删 最近做项目遇到一个Filter需要配置多个url-pattern,上网 ...