C++对象优化

Posted Redamanc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++对象优化相关的知识,希望对你有一定的参考价值。

为什么需要(对象)优化

我们都知道,C语言和C++在程序执行中,都是通过调用一系列的函数来实现的。并且,很多时候,编译器会帮助我们做一系列的事情,比如(在编译类的成员方法的时候,编译器默认添加 this 指针,以此来确定是哪一个对象调用了该成员方法)。
得益于编译器或者说系统帮助我们做的一系列事情,我们可以更加方便地使用C++。
但是凡事有利必有弊,因为系统有时候会自己调用一系列的函数,从另一个角度来说,也一定程度上降低了效率
而我们想要提高C++的执行效率,就需要了解程序(主要是对象)使用过程中都调用了哪些方法。

对象使用过程中都调用了哪些方法

示例代码:

我们首先来看这么一段代码:

#include <iostream>
using namespace std;

class Test
{
public:
	Test(int a = 10)
		:ma(a)
	{
		cout << "Test(int)" << endl;
	}
	~Test()
	{
		cout << "~Test()" << endl;
	}
	Test(const Test& t)
		:ma(t.ma)
	{
		cout << "Test(const Test&)" << endl;
	}
	Test& operator=(const Test& t)
	{
		cout << "operator=" << endl;
		ma = t.ma;
		return *this;
	}
	int getdata()const { return ma; }
private:
	int ma;
};

Test GetObject(Test t) 
{
	int val = t.getdata();
	Test tmp(val);
	return tmp;
}

int main()
{
	Test t1;
	Test t2;
	t2 = GetObject(t1);

	return 0;
}

运行结果:

在这里插入图片描述

结果解释:

我们可以发现,代码中简单的几行,为什么运行结果会有这么多行呢?
实际上,这就是问题所在了。
在这里插入图片描述
详细地:

  • 第一步,主函数中调用构造函数构造t1对象;
  • 第二步,主函数中调用构造函数构造t2对象;
  • 第三步,参数传递过程中,对于对象而言发生初始化而非赋值,所以调用了拷贝构造函数构造形参对象t
  • 第四步,在GetObject()函数中调用构造函数构造对象tmp
  • 第五步,局部对象tmp不能带出函数的作用域,所以,要想把tmp的数值带出来,就需要在主函数的栈帧上tmp拷贝构造一个临时对象;
  • 第六步,局部对象tmp析构;
  • 第七步,局部形参对象t析构;
  • 第八步,主函数main()栈帧上的临时对象赋值t2
  • 第九步,主函数栈帧上的临时对象析构。
  • 第十步,t2析构;
  • 第十一步,t1析构。

对象优化及规则

优化后的结果

在这里插入图片描述
这是优化后的结果,我们可以发现:
实现了同样的功能代码;
优化前,调用了11条语句;
优化后,调用了4条语句;
代码执行的效率得到了大大的提高!

具体优化过程

一、我们可以做如下改动:
原来的:Test GetObject(Test t)
优化后:Test GetObject(Test& t)
做这一步的目的是,减少参数传递过程中的拷贝构造,并且,也少了形参对象的析构,简而言之,少了两条调用语句:
在这里插入图片描述
二、继续优化如下:
原来的:Test tmp(val);return tmp;
优化后:return Test(val);
这一步的目的是,减少局部变量tmp的构造,以及tmp的析构。

我们可以这么理解:
直接用临时对象取代原来定义好的局部对象,
之后用临时对象来构造一个主函数上的新对象
这个时候编译器就会优化,不生成临时对象
直接构造新对象。

在这里插入图片描述
三、继续优化如下:
原来的:Test t2;t2 = GetObject(t1);
优化后:Test t2 = GetObject(t1);
这一步的目的是,省去主函数栈帧上的临时对象的构造和析构,并且省去了赋值函数。
也就是说,这一步优化,省去了3步
在这里插入图片描述

对象优化的三条规则

根据上述过程,我们可以总结规则如下:

  1. 函数参数传递过程中,对象优先按引用传递,不要按值传递;
  2. 函数返回对象的时候,应该优先返回一个临时对象,而不要返回一个定义过的对象;
  3. 接收返回值是对象的函数调用的时候,优先按初始化的方式接收,不要按赋值的方式接收。

以上是关于C++对象优化的主要内容,如果未能解决你的问题,请参考以下文章

C++对象优化

C++对象优化

详细实例说明+典型案例实现 对动态规划法进行全面分析 | C++

这些 C++ 代码片段有啥作用?

有趣的 C++ 代码片段,有啥解释吗? [复制]

以下代码片段 C++ 的说明