C++对象的优化--减少不必要的函数调用

测试环境:win10+vs2013
初始代码:

#include <iostream>
using namespace std;


class Test {
private:
	int ma;
public:
	Test(int data = 10) :ma(data) {
		cout << "Test(int)" << endl;
	}

	Test(const Test& t) :ma(t.ma) {
		cout << "Test(const Test&)" << endl;
	}

	~Test() {
		cout << "~Test()" << endl;
	}

	Test& operator=(const Test& t) {
		ma = t.ma;
		cout << "operator=" << endl;
		return *this;
	}

	int getData() {
		return ma;
	}
};


Test getObject(Test t) {
	int val = t.getData();
	Test res(val);
	return res;
}

int main() {
	Test t1(10);
	Test t2;

	t2 = getObject(t1);
	return 0;
}

执行结果:
上面短短的三行代码,背后居然11次的函数调用,效率太低了!!!

在这里插入图片描述

一、函数参数要求传入对象时,使用引用传递

#include <iostream>
using namespace std;


class Test {
private:
	int ma;
public:
	Test(int data = 10) :ma(data) {
		cout << "Test(int)" << endl;
	}
		
	Test(const Test& t) :ma(t.ma) {
		cout << "Test(const Test&)" << endl;
	}

	~Test() {
		cout << "~Test()" << endl;
	}

	Test& operator=(const Test& t) {
		ma = t.ma;
		cout << "operator=" << endl;
		return *this;
	}

	int getData() {
		return ma;
	}
};

// 相对上边的代码 仅仅是将形式参数 Test t改为Test &t
Test getObject(Test& t) {
	int val = t.getData();
	Test res(val);
	return res;
}

int main() {
	Test t1(10);
	Test t2;

	t2 = getObject(t1);
	return 0;
}

执行结果:
在这里插入图片描述

可以看到,经过函数参数的优化(值传递->引用传递),减少了一次临时对象构造和析构的函数开销。
相对于之前,只有9次的函数调用,减少了两次!!!

二、函数返回时,返回临时对象,不要先定义对象,然后再返回。直接提前计算好构造该函数返回对象所需要的参数,直接返回临时对象。

#include <iostream>
using namespace std;


class Test {
private:
	int ma;
public:
	Test(int data = 10) :ma(data) {
		cout << "Test(int)" << endl;
	}

	Test(const Test& t) :ma(t.ma) {
		cout << "Test(const Test&)" << endl;
	}

	~Test() {
		cout << "~Test()" << endl;
	}

	Test& operator=(const Test& t) {
		ma = t.ma;
		cout << "operator=" << endl;
		return *this;
	}

	int getData() {
		return ma;
	}
};


Test getObject(Test &t) {
	int val = t.getData();
	// Test res(val);
	// return res;
	return Test(val);
}

int main() {
	Test t1(10);
	Test t2;

	t2 = getObject(t1);
	return 0;
}

执行结果:
在这里插入图片描述
相对于上一步优化,又减少了两次函数调用的开销!!!

三、当需要接受一个函数的返回值时,并且该返回值是一个对象,不要以赋值的方式接受,以初始化的方式接受。

#include <iostream>
using namespace std;


class Test {
private:
	int ma;
public:
	Test(int data = 10) :ma(data) {
		cout << "Test(int)" << endl;
	}

	Test(const Test& t) :ma(t.ma) {
		cout << "Test(const Test&)" << endl;
	}

	~Test() {
		cout << "~Test()" << endl;
	}

	Test& operator=(const Test& t) {
		ma = t.ma;
		cout << "operator=" << endl;
		return *this;
	}

	int getData() {
		return ma;
	}
};


Test getObject(Test &t) {
	int val = t.getData();
	// Test res(val);
	// return res;
	return Test(val);
}

int main() {
	Test t1(10);
	Test t2 = getObject(t1);// 初始化的方式接受

	// t2 = getObject(t1); // 赋值的方式接受
	return 0;
}

执行结果:
在这里插入图片描述

相对于初始的代码,同样是获取一个对象的功能,优化到现在只有两次的构造和两次析构的调用,程序减少了相当大的一部分的函数调用开销,程序的效率也得到了很大的提升。一次调用getObejct()函数可以减少7次的函数调用开销,那么100万次的调用,就能减少700万次的开销。量变产生质变!!!

对象优化的三条规则
1.当函数的形式参数需要传递对象时,不要用值接受,用引用接受。减少一次临时对象的构造和析构。
2.当函数的返回值为对象时,不要再函数题先定义好零时对象,然后再返回值。直接提前计算好构造该返回对象需要的参数,直接返回一个临时对象。
3.当接受函数返回值为对象的函数的返回值时,以初始化的方式接受,不要以赋值的方式接受。
tips:当以临时对象拷贝构造一个新对象时,编译器不会产生这个临时对象,直接以构造临时对象的方式直接构造新对象,减少一次临时对象的构造和析构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值