函数的调用优化

函数的调用优化

在类中有四大成员函数,构造函数,拷贝构造函数,赋值函数和析构函数,在类外进行实例化时,若调用函数的方法不当则会产生时间和空间的浪费。

以下,将用几个小栗子来说明函数的调用优化的常见办法

类:

class Test
{
public:
	Test(int d = 0)
		: _data(d)
	{
		cout << "Create Test Object:"<<this << endl;
	}
	Test(const Test&x)
		:_data(x._data)
	{
		cout << "Copy Create Object:" <<this<< endl;
	}
	Test&operator=(const Test&x)
	{
		cout << "Assign:"<<this << endl;
		if (this != &x)
		{
			_data = x._data;
		}
		return *this;
	}
	~Test()
	{
		cout << "Free Test Object:"<<this << endl;
	}
public:
	int GetData() const
	{
		return _data;
	}
private:
	int  _data;
};

方法

Test fun(Test x)
{
	int value = x.GetData();
	Test tmp(value);
	return tmp;
}
void main()
{
	Test t1(100);//构造
	Test t2;//拷贝构造
	t2 = fun(t1);
	/*
	1.fun函数的参数先做一份零时拷贝,调用构造函数;
	2.用value拷贝构造tmp;
	3.返回tmp时再用tmp创建临时变量,调用拷贝构造函数;
	4.出这个函数域后,创建的临时变量进行析构,即x和tmp;
	5.返回的值给t2赋值,调用赋值语句
	6.完成完赋值语句后,析构临时的无名对象(tmp的)
	7.析构t2、t1。
	*/
	getchar();
}

以上是未优化的方法,其占用空间,浪费时间

优化1:

Test fun(Test x)
{
	int value = x.GetData();
	return Test(value);//创建无名临时变量,创建出的变量无名字
	/*
		返回时一般都会拷贝一个临时变量再返回,但这里编译器进行了优化
	直接进行构造了一个无名临时变量(减少了一次拷贝构造函数的调用和析构)
	*/
}
void main()
{
	Test t1(100);
	Test t2;
	t2 = fun(t1);
	/*
	直接用返回的无名临时变量对t2进行赋值
	*/
	getchar();

}

优化2

Test fun(Test&x)
{
	/*
	fun函数中的参数是引用传参,x不用再创建临时对象,省去了拷贝构造函数的调用
	*/
	int value = x.GetData();
	return Test(value);
}

优化3

int main()
{
	Test t1(100);
	Test t2=fun(t1);
	//初始化,只调用构造函数
	getchar();
}

优化后只调用两次构造函数,两次析构函数

ps:错误优化

Test &fun(Test&x)
{
	int value = x.GetData();
	return Test(value);
	//返回时不能返回无名临时变量,由于这个是引用返回,一出函数域就被析构,其值不存在

}

关于一个函数是否可以引用返回要看这个对象是否为局部对象,若受这个函数域影响,则不能进行引用返回

时间: 2024-10-21 09:12:39

函数的调用优化的相关文章

使用 __declspec(dllimport) 能够优化对DLL导出函数的调用.

使用 __declspec(dllimport) 能够优化对DLL导出函数的调用. 不使用时: [DLL] #ifdef THEDLL_EXPORTS #define THEDLL_API __declspec(dllexport) #else #define THEDLL_API __declspec(dllimport) #endif // THEDLL_API int fntheDll(void); [EXE] #include "..\\theDll\\theDll.h" #p

写日志函数和持续优化

首先看下面的函数 <span style="font-size:18px;">void writelog(char* file, char* msg) { FILE*fp=NULL; int nDataLen = strlen(msg); fp=fopen(file,"ab+");//只供读取 if(fp!=NULL) { fwrite(msg, nDataLen, 1, fp); } fclose(fp);//关闭文件 }</span> 这

MonoBehavior的调用优化

本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/70921049 作者:cartzhang 本文同步与游戏蛮牛. MonoBehavior的调用优化 如果告诉你,Unity由于调用你的MonoBehaviour函数而造成CPU性能大量浪费?真的与你的脚本无关么?若你有成千上百个呢,你应该了解一个新的优化领域. 魔术技巧 MonoBehaviour函数调用缓慢.我们谈论的是像U

c/c++与函数有关的优化

一.函数调用的优化 调用函数需要对内存进行多次访问,因此对函数的调用通常很费时,容易造成程序效率低下: 在函数调用过程中,如果每一次函数的调用结果都相同且需要多次调用时,可以将几次调用的结果进行多次累加,以避免函数多次调用带来的效率低下: 二.变量存储优化 对频繁使用的变量和只在一定范围内的变量,尽可能将其设定为局部变量,因为局部变量会被存储在寄存器中,而全局变量则被存储在了内存数据段上,cpu对内存的访问速度远远低于访问本身寄存器.对比一下: 先来看第一个程序: int i: foo() {

逆向知识十一讲,识别函数的调用约定,函数参数,函数返回值.

逆向知识十一讲,识别函数的调用约定,函数参数,函数返回值. 在反汇编中,我们常常的会看到各种的函数调用,或者通过逆向的手段,单独的使用这个函数,那么此时,我们就需要认识一下怎么识别函数了. 一丶识别__cdecl 函数(俗称C Call),函数参数,函数返回值 首先写一个C Call的函数 1.返回值 int类型, 参数int 类型 高级代码: int __cdecl MyAdd(int a,int b) { return a + b; } int main(int argc, char* ar

FFmpeg av_probe_input_buffer函数剖析以及优化

函数调用关系av_probe_input_buffer调用av_probe_input_buffer2进行整一个码流格式的分析过程.其中调用avio_read进行码流数据的读取,将缓存数据保存在AVProbeData定义的buf里面,然后调用av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max)函数去猜测码流格式,其中包裹最终的调用函数av_probe_input_format3. 优化方向如果知道AVInpu

尾调用优化和尾递归改写

1 尾调用 尾调用就是指某个函数的最后一步是调用另一个函数. # 是尾调用 def f(x): return g(x) # 不是尾调用,因为调用函数后还要执行加法,加法才是最后一步操作 def f(x): return 1+g(x) 2 尾调用优化 函数调用有一个调用栈,栈内保存了这个函数内部的变量信息.函数掉用就是切换不同的调用帧,从而保证每个函数有独立的运行环境.因为尾调用是函数的最后一步操作,所以在进入被尾调用函数之前并不需要保留外层函数的运行时环境,因为调用位置.内部变量等信息都不会再用

深入剖析php执行原理(4):函数的调用

本章开始研究php中函数的调用和执行,先来看函数调用语句是如何被编译的. 我们前面的章节弄明白了函数体会被编译生成哪些zend_op指令,本章会研究函数调用语句会生成哪些zend_op指,等后面的章节再根据这些op指令,来剖析php运行时的细节. 源码依然取自php5.3.29. 函数调用 回顾之前用的php代码示例: <?php function foo($arg1) { print($arg1); } $bar = 'hello php'; foo($bar); 在函数编译一章里已经分析过,

javascript学习笔记(二):定义函数、调用函数、参数、返回值、局部和全局变量

定义函数.调用函数.参数.返回值 关键字function定义函数,格式如下: function 函数名(){ 函数体 } 调用函数.参数.返回值的规则和c语言规则类似. 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta chaset="UTF-8"> 5 <title></title> 6 </head> 7 <body