C++——调用优化
原始代码
#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++——调用优化的更多相关文章
- JavaScript中的尾调用优化
文章来源自:http://www.zhufengpeixun.com/qianduanjishuziliao/javaScriptzhuanti/2017-08-08/768.html JavaScr ...
- 前端项目中常用es6知识总结 -- 箭头函数及this指向、尾调用优化
项目开发中一些常用的es6知识,主要是为以后分享小程序开发.node+koa项目开发以及vueSSR(vue服务端渲染)做个前置铺垫. 项目开发常用es6介绍 1.块级作用域 let const 2. ...
- ES6躬行记(15)——箭头函数和尾调用优化
一.箭头函数 箭头函数(Arrow Function)是ES6提供的一个很实用的新功能,与普通函数相比,不但在语法上更为简洁,而且在使用时也有更多注意点,下面列出了其中的三点: (1)由于不能作为构造 ...
- js 调用栈机制与ES6尾调用优化介绍
调用栈的英文名叫做Call Stack,大家或多或少是有听过的,但是对于js调用栈的工作方式以及如何在工作中利用这一特性,大部分人可能没有进行过更深入的研究,这块内容可以说对我们前端来说就是所谓的基础 ...
- ES6学习笔记 -- 尾调用优化
什么是尾调用? 尾调用(Tail Call)是函数式编程的一个重要概念,就是指某个函数的最后一步是调用另一个函数. function f(x) { return g(x) } 如上,函数 f 的最后一 ...
- iOS 的尾调用优化原理
背景: 今天聊代码规范的问题的时候说了一下尾调用的问题. 一:概念: 什么是尾调用? 尾调用(Tail Call):某个函数的最后一步仅仅只是调用了一个函数(可以是自身,可以是另一个函数). 注意 “ ...
- JVM反调调用优化,导致发生大量异常时log4j2线程阻塞
背景 在使用log4j2打日志时,当发生大量异常时,造成大量线程block问题的问题. 一个关于log4j2的高并发问题:https://blog.fliaping.com/a-high-concur ...
- springcloud 之 feign的重复性调用 优化
最近有一个springcloud的feign请求,用于获取坐标经纬度的信息,返回结果永远是固定不变的,所以考虑优化一下,不然每次转换几个坐标都要去请求feign,返回的所有坐标信息,数据量太大导致耗时 ...
- C#.NET 大型企业信息化系统集成快速开发平台 4.2 版本 - 外部服务调用、内部服务调用优化,面向服务化的
现在的信息系统越来越复杂,越来越庞大,不仅需要内部是一个整体,而且还需要提供很多对外的服务调用. 1:别人如何调用最方便?用不同的开发语言调用.例如app.手持设备.服务器.2:服务的返回状态是什么样 ...
随机推荐
- Jackson解析自定义json到实体类
json文本 { "status": 0, "result": { "final": true, "hypotheses" ...
- DBGrid中插入DateTimePicker
DateTimePicker inside a DBGrid Here's how to place a TDateTimePicker into a DBGrid. Create visually ...
- 05点睛Spring4.1-国际化
5.1 ReloadableResourceBundleMessageSource 使用ReloadableResourceBundleMessageSource可获得不同语言的配置 此处是全局配置, ...
- Flutter状态管理之provide和provider的使用区别
说道状态管理不得不说谷歌的亲自开发的两款状态管理Widget:第一个是provide,第二个是provider. 这两个的区别就是一个出来的早,现在好像没整么更新了.第二个是2019才出来的目前的版本 ...
- String类的构造函数,析构函数、拷贝构造函数和赋值函数
(1)构造函数 String::String(const char *str) { if(str==NULL) { m_data = new char[1]; *m_data = ‘\0’; } el ...
- linux-rsync-同步本地文件夹
linux-rsync-同步本地文件夹 1.安装rsync: yum list rsync yum install rsync 3.使用rsync命令进行同步 rsync -av 源目录 目标目录
- start use webpack
Demo0操作手册 本Demo演示不使用配置文件的入门级使用 准备环境 初始化环境, cd到demo目录之后, 执行如下命令: npm init -y npm install webpack webp ...
- LeetCode 242. 有效的字母异位词(Valid Anagram)
242. 有效的字母异位词 LeetCode242. Valid Anagram 题目描述 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的一个字母异位词. 示例 1: 输入: s ...
- 解决idea tomcat乱码问题
解决idea Server Output.TomcatLocalhost Log.Tomcat Catalina Log控制台乱码问题 问题原因:编码不一致,tomcat启动后默认编码UTF-8,而w ...
- fpga基础
1.FPGA 的分类: 根据 FPGA 基本结构,可将其分为基于乘积项(Product-Term)技术的 FPGA 和基于查找表(Look-Up-Table)技术的 FPGA 两种. (1)基于乘积项 ...