学生大本营中有同学提出这个问题,感觉有一定代表性,这里做个回答。
一家之言哈,欢迎拍砖。
问题:
   C++中当函数返回值类型时,系统会默认调用拷贝构造函数将返回值复制到函数作用域外,然后销毁超出作用域的对象,再将作用域外的临时对象拷贝到接收对象中。基于此问题,在下一直以为,不应该依靠“隐式”的行为。而数周之前在《C++编程思想》中不慎找到了解决该问题的理论,但由于其理论过于合理以致代码测试拖到了日前进行,目前的问题在于:基于我所理解的该书中描述的理论,我所设计的代码并不能正确运行,因此想在此请教各位。
    根据记忆,该书中出现的理论大概是这么个意思:
struct  X
{
      int num;
};
X  fun (const  X   &test)
{
      X  copy;
      copy.num=test.num;
      return   copy;
}
在这里书上指出了这个fun函数存在性能损失:在函数作用域内建立了一个对象,在超出作用域之后它必须被销毁,而在返回类型值的时候又必须调用一次拷贝构造函数以建立函数作用域外的临时对象,如此一来增加了无谓的性能损失。问题的关键在于,书上说可以将代码改写成如此形式提高性能:
X   fun  (const X  &text)
{
      return    X(test);
}
一旦改成如此形式,由于构造函数位于return语句中,那么此代码的效果将指示编译器直接将临时对象创建在函数作用域之外而省去了一次对象的创建和销毁工作。
    现在进入主题:如果按照这个理论,那么我认为改写之后的函数是属于显式调用拷贝构造函数而将临时对象创建在了函数作用域外,也就是说,如果此理论成立,那么即使我将拷贝构造函数声明为explicit的,那么测试这种机制的代码也应该能通过编译并运行——我显式地调用了拷贝构造函数传值。但是,从我测试的代码来看,即使使用第二个版本的函数也还是会隐式地调用拷贝构造函数。
    那么我想问的是,如何在不使用引用和指针,也不使用包装器函数的情况下,在函数返回值类型的过程中消除构造函数的隐式调用?
    具体一些的话就是:如果我将拷贝构造函数声明为explicit的,不使用引用和指针,也不使用包装器,如何设计返回值类型的函数?
    我使用的编译器是gcc,IDE是DEVCPP 4.9.9.2 。
我的回答:
这个问题很怪异,我觉得甚至不是一个问题。
首先,一般说来,我的习惯,不会使用struct的C++特性,如果要定义类,用class更好一点。struct用来存放纯数据较好。
一般不建议返回复杂的函数返回值,比如你文中的例子,一定要返回一个对象,我的习惯是不要这么做。
在C和C++语言中,我一般习惯于区分简单变量和复杂变量,int这类基本类型属于简单变量,系统可以默认拷贝,处理就很简单,而对象,结构体实例一般数据复杂变量,一般不建议使用函数返回值形式默认返回。一般是单独构建一个Copy函数,来针对性做拷贝动作,避免出错。
原则很简单,就是不要在函数中向外返回复杂变量,里面太多隐式操作,不直观,不明显。给自己造成潜在bug的可能性,就不划算了。
因此,上述拷贝构造函数,我其实在工程中,一次都没有用过,这么多年也算把饭钱赚到手了,呵呵。
至于你说的性能损失,我要说有点吹毛求疵了。事实上,基于编译器的性能损失,我一般不考虑,因为实际工程中,有时候,换个算法,早就找补回来了。如果一个系统会对这点性能损失敏感,首先说明的是这个系统有问题,需要改系统设计。
因此,除了做游戏时,有时候高速图形刷屏,对编译器级的性能敏感外,一般工程应用,都不考虑这个问题。
我们考虑更多的,反而是架构的合理性。多一个无谓的节点,拓扑角色,有时候带来的性能的损失更大。
一般说来,就语言谈语言,而不是和具体工程应用结合着讨论,一般性能意义不大。

转载于:https://blog.51cto.com/tonyxiaohome/198796

商用工程开发中的一些习惯相关推荐

  1. 《0 bug ---- C/C++商用工程之道》目录

    扉页 前言 1.1  为什么要写本书? 1.2  本书包括哪些内容 1.3  商用工程开发和软件编程的区别 1.4   商用程序员的核心思想 1.5  本书适合哪些读者看 1.6  本书中一些名词解释 ...

  2. 关于概率分布理论的原理分析的一些讨论,以及经典概率分布的应用场景,以及概率统计其在工程实践中的应用...

    1. 随机变量定义 0x1:为什么要引入随机变量这个数学概念 在早期的古典概率理论研究中,人们基于随机试验的样本空间去研究随机事件,也发展出了非常多辉煌的理论,包括著名的贝叶斯估计在内. 但是随着研究 ...

  3. 项目的命名规范,为以后的程序开发中养成良好的行为习惯

    代码编写规范目的:能够在编码过程中实现规范化,为以后的程序开发中养成良好的行为习惯. 代码编写规范使用范围:J2EE项目开发. 一.包命名规范: 目的:包的命名规范应当体现出项目资源良好的划分 1.s ...

  4. 网络推广外包中目标用户习惯对企业网站设计与开发有重要影响

    众所周知,在企业网站设计与开发过程中,左右企业网站开发设计走向的最主要的就是用户,以用户为核心.立足于用户角度.关注用户浏览习惯等等,这些内容的了解对于目标用户群体进一步接受企业产品或服务也更容易,在 ...

  5. 实际工作开发中C语言工程的目录结构分析

    1.前言 (1)工作开发中,一个项目是十分复杂的,必须要有清晰的工程目录框架去管理整个工程,使源文件.头文件.库文件都在合适的目录下,能降低整个开发过程以及后续维护的难度: (2)下面介绍的工程目录结 ...

  6. api工程IOS学习:在IOS开发中使用GoogleMaps SDK

    今天一直在学习api工程之类的问题,今天正好有机会和大家分享一下. 官方文档地址:https://developers.google.com/maps/documentation/ios/start# ...

  7. 制造业产品开发中应用敏捷Scrum的思考 (下篇)

    上篇作者作为一名机械制造业的从业者,简单介绍了敏捷Scrum,并分享了一些对Scrum理念的理解.下篇以制造业产品开发中应用敏捷Scrum的思考进行了一系列的分享. 点击链接阅读: 敏捷Scrum理念 ...

  8. 浅谈Excel开发:九 Excel 开发中遇到的常见问题及解决方法

    Excel开发过程中有时候会遇到各种奇怪的问题,下面就列出一些本人在开发中遇到的一些比较典型的问题,并给出了解决方法,希望对大家有所帮助. 一 插件调试不了以及错误导致崩溃的问题 在开发机器上,有时可 ...

  9. 关于《0 bug -- C/C++商用工程之道》的一处bug

    这两天有很多朋友已经买了书了,并且开始看,呵呵,我心里也很高兴. 嗯,要说江湖上藏龙卧虎呢,这不,这才几天时间,已经有朋友指出我书中的一处明显错误,这里我正式给大家说明一下,免得对各位读者有个不好的误 ...

最新文章

  1. 谷歌控制面板中的NetWrok
  2. 北京计算机一级2020,2020北京市一级计算机基础及MS Office应用考试在线自测试题库(不限设备,登陆即可做题)...
  3. python实现队列_Python学习教程:用队列实现栈
  4. C语言文件打开方式及说明
  5. Python爬虫学习round01
  6. RHEL4下刻录机使用--终端图形化方式
  7. oraccle 索引管理
  8. 类似taobao的多彩选项卡tab
  9. 适用于苹果Mac的 4 个好用的 CAD 软件
  10. 用友软件常用名词解释
  11. B4A-Basic4android
  12. 开通一个博客,开启一个更高的要求
  13. [单片机框架][bsp层][cx32l003][bsp_system_clock] clock配置和使用
  14. 约瑟夫环 java_约瑟夫环的java实现
  15. [宋史学习] 赵光义篡改历史
  16. DNF 单机游戏 手机游戏 网络游戏 推荐游戏 TXT 小说 外挂 辅助
  17. cpu第几代计算机,赛扬G系列有几代cpu分别是
  18. 卷积神经网络与全连接神经网络
  19. python计算学分绩点_使用Python计算研究生学分绩(绩点)
  20. python 形态学

热门文章

  1. python课程设计矩阵对角线之和,为每个python numpy用不同的值填充矩阵对角线
  2. 怎么把东西去掉修图_很多人花几千块学习商业修图,其实跟把钱扔了一样。?...
  3. java dfs算法蓝桥杯题_【蓝桥杯省赛JavaB组真题详解】四平方和(2016)_疼疼蛇的博客-CSDN博客...
  4. 极光推送指定用户推送_App用户都睡着了?是时候用推送和活动唤醒一波了!
  5. 计算机能做什么英语对话,计算机英语会话∣实用电脑英语
  6. javascript中作用域、全局作用域、局部作用域、隐式全局变量、块级作用域、作用域链、预解析
  7. Zookeeper集群为什么要是单数
  8. 2021年中国健康险行业创新研究报告
  9. 不爱沟通的人可以做产品经理嘛?
  10. 十进制转二进制 java 程序_如何把一个十进制数转为二进制数的Java程序?