原始代码

 #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. tp 执行sql 语句

    $User = D('User'); $User->query('select * from think_user where status=1'); $User->execute('up ...

  2. html如何修改hr水平直线的粗细

    hr是常见的超文本标签,是一条水平直线,要设置该直线变粗一些.可以先把hr本身的border隐藏掉,然后设置border-top-width,也就是只留上边框,如图:hr的默认高度height是0,所 ...

  3. Java基础教程:多线程杂谈——双重检查锁与Volatile

    Java基础教程:多线程杂谈——双重检查锁与Volatile 双重检查锁 有时候可能需要推迟一些高开销的对象初始化操作,并且只有在使用这些对象时才进行初始化.此时程序员可能会采用延迟初始化.但要正确实 ...

  4. 时空卷积网络TCN

    1.写在前面 实验表明,RNN 在几乎所有的序列问题上都有良好表现,包括语音/文本识别.机器翻译.手写体识别.序列数据分析(预测)等. 在实际应用中,RNN 在内部设计上存在一个严重的问题:由于网络一 ...

  5. 【tensorflow】softmax_cross_entropy_with_logits与sparse_softmax_cross_entropy_with_logits

    softmax_cross_entropy_with_logits与sparse_softmax_cross_entropy_with_logits都是对最后的预测结果进行softmax然后求交叉熵 ...

  6. win10中禁用Ctrl+Alt+上下左右箭头的方法

    win10的Ctrl+Alt+向左/右/上/下箭头,与pycharm中的快捷键有冲突,需要禁用 右键''显示设置''---->高级显示设置------->显示器1的显示适配属性-----& ...

  7. 为nologin用户开一个terminal

    昨天,我在设置zabbix-agent的时候,发现agent机器上的zabbix用户并不能读取某文件信息.我就想跳到zabbix用户,后来失败,发现在/etc/passwd中,zabbix被设置为 z ...

  8. 【转帖】docker 如何删除none镜像

    https://blog.csdn.net/hicoldcat/article/details/80802447 shell 命令博大精深 需要仔细学习 删除none的镜像,要先删除镜像中的容器.要删 ...

  9. vue elementui如何修改el-table头部样式

    找到el-table加入红色代码 <el-table :row-style="tableRowStyle" :header-cell-style="tableHea ...

  10. js 自定义加减乘除方法(防止js自身计算错误)

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...