原始代码

 #include<iostream>
using namespace std;
class Test {
public:
//以参数列表形式对数据成员进行初始化
Test(int d = ) :data(d)
{
cout << "Create Test Object:" << this << endl;
}
Test(const Test &t)
{
cout << "Copy Create Test Object:" << this << endl;
this->data = t.data;
}
Test& operator=(const Test &t)
{
cout << "Assign:" << this << "=" << &t << endl;
if (this != &t)
{
this->data = t.data;
}
return *this;
}
~Test()
{
cout << "Free Test Object:" << this << endl;
}
int GetData()
{
return data;
}
private:
int data;
}; Test fun(Test t)
{
int value = t.GetData();
Test tmp(value);
return tmp;
} int main(int argc, char **argv)
{
Test t1();
Test t2 ;
t2 = fun(t1);
return ;
}

有结果观察可知,fun函数里面,tmp这个临时对象被创建的意义仅仅是为了调用拷贝构造函数初始化一个临时对象。初始化临时对象完毕后就被析构了。

代码优化,创建无名临时对象

 #include<iostream>
using namespace std;
class Test {
public:
//以参数列表形式对数据成员进行初始化
Test(int d = ) :data(d)
{
cout << "Create Test Object:" << this << endl;
}
Test(const Test &t)
{
cout << "Copy Create Test Object:" << this << endl;
this->data = t.data;
}
Test& operator=(const Test &t)
{
cout << "Assign:" << this << "=" << &t << endl;
if (this != &t)
{
this->data = t.data;
}
return *this;
}
~Test()
{
cout << "Free Test Object:" << this << endl;
}
int GetData()
{
return data;
}
private:
int data;
}; Test fun(Test t)
{
int value = t.GetData();
return Test(value);//创建无名临时对象
} int main(int argc, char **argv)
{
Test t1();
Test t2 ;
t2 = fun(t1);
return ;
}

fun函数return返回那里没有再调用拷贝构造函数

代码继续优化,fun函数参数改为传引用

 #include<iostream>
using namespace std;
class Test {
public:
//以参数列表形式对数据成员进行初始化
Test(int d = ) :data(d)
{
cout << "Create Test Object:" << this << endl;
}
Test(const Test &t)
{
cout << "Copy Create Test Object:" << this << endl;
this->data = t.data;
}
Test& operator=(const Test &t)
{
cout << "Assign:" << this << "=" << &t << endl;
if (this != &t)
{
this->data = t.data;
}
return *this;
}
~Test()
{
cout << "Free Test Object:" << this << endl;
}
int GetData()
{
return data;
}
private:
int data;
}; Test fun(Test &t)
{
int value = t.GetData();
return Test(value);//创建无名临时对象
} int main(int argc, char **argv)
{
Test t1();
Test t2 ;
t2 = fun(t1);
return ;
}

在继续优化,fun函数返回引用

 #include<iostream>
using namespace std;
class Test {
public:
//以参数列表形式对数据成员进行初始化
Test(int d = ) :data(d)
{
cout << "Create Test Object:" << this << endl;
}
Test(const Test &t)
{
cout << "Copy Create Test Object:" << this << endl;
this->data = t.data;
}
Test& operator=(const Test &t)
{
cout << "Assign:" << this << "=" << &t << endl;
if (this != &t)
{
this->data = t.data;
}
return *this;
}
~Test()
{
cout << "Free Test Object:" << this << endl;
}
int GetData()
{
return data;
}
private:
int data;
}; Test& fun(Test &t)
{
int value = t.GetData();
return Test(value);//创建无名临时对象
} int main(int argc, char **argv)
{
Test t1();
Test t2 ;
t2 = fun(t1);
return ;
}

这段代码在VS2017下编译不过,分析原因如下

return Test(value);//创建无名临时对象

无名临时对象出了函数就被释放了,t2 = fun(t1);调用赋值函数,是将一个已被析构的对象赋值给具体对象t2。

函数返回值能否写成引用,要看所引用的对象是否是局部对象,如果出了函数对象被析构了就不要引用。

代码继续优化

 #include<iostream>
using namespace std;
class Test {
public:
//以参数列表形式对数据成员进行初始化
Test(int d = ) :data(d)
{
cout << "Create Test Object:" << this << endl;
}
Test(const Test &t)
{
cout << "Copy Create Test Object:" << this << endl;
this->data = t.data;
}
Test& operator=(const Test &t)
{
cout << "Assign:" << this << "=" << &t << endl;
if (this != &t)
{
this->data = t.data;
}
return *this;
}
~Test()
{
cout << "Free Test Object:" << this << endl;
}
int GetData()
{
return data;
}
private:
int data;
}; Test fun(Test &t)
{
int value = t.GetData();
return Test(value);//创建无名临时对象
} int main(int argc, char **argv)
{
Test t1();
Test t2 = fun(t1);
return ;
}

C++——调用优化的更多相关文章

  1. JavaScript中的尾调用优化

    文章来源自:http://www.zhufengpeixun.com/qianduanjishuziliao/javaScriptzhuanti/2017-08-08/768.html JavaScr ...

  2. 前端项目中常用es6知识总结 -- 箭头函数及this指向、尾调用优化

    项目开发中一些常用的es6知识,主要是为以后分享小程序开发.node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫. 项目开发常用es6介绍 1.块级作用域 let const 2. ...

  3. ES6躬行记(15)——箭头函数和尾调用优化

    一.箭头函数 箭头函数(Arrow Function)是ES6提供的一个很实用的新功能,与普通函数相比,不但在语法上更为简洁,而且在使用时也有更多注意点,下面列出了其中的三点: (1)由于不能作为构造 ...

  4. js 调用栈机制与ES6尾调用优化介绍

    调用栈的英文名叫做Call Stack,大家或多或少是有听过的,但是对于js调用栈的工作方式以及如何在工作中利用这一特性,大部分人可能没有进行过更深入的研究,这块内容可以说对我们前端来说就是所谓的基础 ...

  5. ES6学习笔记 -- 尾调用优化

    什么是尾调用? 尾调用(Tail Call)是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数. function f(x) { return g(x) } 如上,函数 f 的最后一 ...

  6. iOS 的尾调用优化原理

    背景: 今天聊代码规范的问题的时候说了一下尾调用的问题. 一:概念: 什么是尾调用? 尾调用(Tail Call):某个函数的最后一步仅仅只是调用了一个函数(可以是自身,可以是另一个函数). 注意 “ ...

  7. JVM反调调用优化,导致发生大量异常时log4j2线程阻塞

    背景 在使用log4j2打日志时,当发生大量异常时,造成大量线程block问题的问题. 一个关于log4j2的高并发问题:https://blog.fliaping.com/a-high-concur ...

  8. springcloud 之 feign的重复性调用 优化

    最近有一个springcloud的feign请求,用于获取坐标经纬度的信息,返回结果永远是固定不变的,所以考虑优化一下,不然每次转换几个坐标都要去请求feign,返回的所有坐标信息,数据量太大导致耗时 ...

  9. C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 外部服务调用、内部服务调用优化,面向服务化的

    现在的信息系统越来越复杂,越来越庞大,不仅需要内部是一个整体,而且还需要提供很多对外的服务调用. 1:别人如何调用最方便?用不同的开发语言调用.例如app.手持设备.服务器.2:服务的返回状态是什么样 ...

随机推荐

  1. SpringBoot中日志配置

    背景 由于一些框架中还使用log4j-1.x系列陈旧的日志框架,调试过程中有一些错误信息不能在控制台显示,增加了调试成本.以下配置方法 将帮助你获得log4j-1.x日志在控制台显示. 解决方法: 使 ...

  2. Apache使用内置插件mod_php解析php的配置

    apache安装完毕之后,修改httpd.conf配置文件,添加代码如下: LoadModule php5_module modules/libphp5.so <FilesMatch \.php ...

  3. 【Tools】ModbusSlave 7.0和ModbusPoll 7.0官网最新软件+注册码

    某宝1.5元淘的:有币的求赏,小弟下载缺币.没币的从附件下载. 赏币地址:https://download.csdn.net/download/qq_18187161/10724794 谢谢! 无币百 ...

  4. Docker 安装运行MSSQL Server

    1.镜像主页 https://hub.docker.com/_/microsoft-mssql-server 2.拉取2017最新版 docker pull mcr.microsoft.com/mss ...

  5. Pycharm use GUP server

    1.配置远程服务器信息 Tools——Deployment——Configuration 然后,点击加号Add一个远程服务信息. 我这里命名为server1:Type选择SFTP:Host即ip地址, ...

  6. PS更换证件照背景颜色

    同学们大家好,我是阿宝老师,今天给大家讲一下如何使用PS更换证件照背景色. 目前使用PS更换证件照底片有三种方式,这三种方式虽有不同,但是最终目的都是将人像从背景中抠出来.扣取人像有三种方法可供选取, ...

  7. php实现文件与16进制相互转换

    php实现文件与16进制相互转换 <pre><?php/** * php 文件与16进制相互转换 * Date: 2017-01-14 * Author: fdipzone * Ve ...

  8. Python 模块初始化的时候,发生了什么?

    假设有一个 hello.py 的模块,当我们从别的模块调用 hello.py 的时候,会发生什么呢? 方便起见,我们之间在 hello.py 的目录下使用 ipython 导入了. hello.py ...

  9. python基础学习(八)

    17.嵌套循环 # 嵌套循环 nested loop # 在一个循环中使用另外一个循环 num_list1 = [1, 2, 3, 4] num_list2 = [6, 7, 8, 9] # 组合li ...

  10. Oracle 11g xe版本---总结1

    一.创建用户和授予权限 1.1 环境: Oracle 11g xe 第三方图形客户端: PLSQL Windows 10 必须登录 HR 用户,下面的查询会使用到 HR 中的表. 1.2 SQL 语句 ...