原始代码

 #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. 【NANO】引脚说明

    http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=489650&page=1

  2. ubuntu18.04安装DB2 11.1 Express-c

    参考连接:https://developer.ibm.com/answers/questions/280797/download-db2-express-c-105-1/ 这个参考页面提供了DB2 E ...

  3. 静态站点生成器-html-markdown-jekyll

    推荐指数:

  4. web端自动化——Selenium Server环境配置

    Selenium Server环境配置 下面下载.配置并运行Selenium Server. ①    下载 Selenium Server. 下载地址为:https://pypi.python.or ...

  5. popup demo

    Django下实现: urls.py: from django.conf.urls import url from django.contrib import admin from app01 imp ...

  6. Appium移动自动化测试-----(九) appium API 之应用操作

    1.安装应用 方法: installApp() 安装应用到设备中去.需要apk包的路径. driver.installApp("path/to/my.apk"); driver.i ...

  7. LeetCode 605. 种花问题(Can Place Flowers) 6

    605. 种花问题 605. Can Place Flowers 题目描述 假设你有一个很长的花坛,一部分地块种植了花,另一部分却没有.可是,花卉不能种植在相邻的地块上,它们会争夺水源,两者都会死去. ...

  8. Cookies和Sessions

    Cookie和Session 为什么会有cookie和session? 由于http协议是无状态的 无法记住用户是谁,cookie主要是在浏览器上记录客户的状态,session主要是用来在服务端记录客 ...

  9. 修改Linux服务器中的MySql密码

    1.可以直接在数据库中修改,因为知道root密码,所以直接登录 mysql -uroot -p 2.查看一下数据库,修改root密码需要使用如下图所示的mysql数据库 3.通过use mysql指明 ...

  10. 虚拟机性能监控与故障处理工具(深入理解java虚拟机三)

    JDK自带的工具可以方便的帮助我们处理一些问题,包括查看JVM参数,分析内存变化,查看内存区域,查看线程等信息. 我们熟悉的有java.exe,javac.exe,javap.exe(偶尔用),jps ...