14.13 临时对象深入探讨、解析与提高性能手段

一:临时对象的概念

i++,++i
int i = 1;
int&& r1 = i++; //r1和i之间没有什么关系
r1 = 19;
i = 80;

另外一些临时对象,是因为我们代码书写问题而产生的。统一称临时变量为临时对象。new /delete、栈。

二:产生临时对象的情况和解决,三种情况和解决方案

<1>以传值的方式给函数传递参数 CTempValue

class CTempValue
{
public:
	int val1;
	int val2;
public:
	CTempValue(int v1 = 0, int v2 = 0);  //构造函数
	CTempValue(const CTempValue& v) : val1(v.val1), val2(v.val2)
	{
		cout << "调用了拷贝构造函数" << endl;
	}

	CTempValue& operator=(const CTempValue& tempv)
	{
		cout << "调用了拷贝赋值运算符" << endl;
		cout << "tempv.val1: " << tempv.val1 << endl;
		cout << "tempv.val2: " << tempv.val2 << endl;
		return *this;
	}
	virtual ~CTempValue()
	{
		cout << "调用了析构函数" << endl;
	}
public:
	int Add(CTempValue& tobj);
};

CTempValue::CTempValue(int v1, int v2) : val1(v1), val2(v2)
{
	cout << "调用了构造函数" << endl;
	cout << "val1 = " << val1 << endl;
	cout << "val2 = " << val2 << endl;
}

int CTempValue::Add(CTempValue& tobj)
{
	int temp = tobj.val1 + tobj.val2;
	tobj.val1 = 1000;
	return temp;
}

int main()
{
	CTempValue tv(10, 20);  //调用构造函数
	cout << "***********************" << endl;
	int sum = tv.Add(tv);  //这个会导致拷贝构造函数的执行
	cout << "***********************" << endl;
	cout << "sum = " << sum << endl;
	cout << "tv.val1 = " << tv.val1 << endl;
	cin.get();
	return 0;
}

<2>类型转换生成临时对象 / 隐式类型转换以保证函数调用成功

CTempValue sum;
sum = 1000; //这里产生了一个真正的临时对象

1>用1000这个数字创建了一个类型为CTempValue的临时对象
2>调用拷贝赋值运算符把这个临时对象里面的各个成员值赋值给了sum对象,
3>销毁这个临时创建的CTempValue

CTempValue sum = 1000; //把定义对象和给对象初值放在一行上。这个等号不是赋值运算符了,是定义时初始化。为sum对象预留了空间,用1000构造 sum 对象,而且是直接构造在 sum 对象的预留空间里。

隐式类型转换以保证函数调用成功
char mystr[100] = “I love China, oh, yeah!”;
string mystr2 = “I love China, oh, yeah!”;
int result = calc(mystr, ‘o’); //char[], string
C++语言只会为const引用 (const string& strsource) 产生临时变量,而不会为非 const 引用 (string& strsource) 这种参数产生临时变量。

int calc(const string& strsource)
{
	cout << "int calc(const string& strsource)" << endl;
	const char* p = strsource.c_str();
	cout << "p: " << p << endl;
	int icount = 0;
	return icount;
}

int calc(string& strsource)
{
	cout << "int calc(string& strsource)" << endl;
	const char* p = strsource.c_str();
	cout << "p: " << p << endl;
	int icount = 0;
	return icount;
}

int main()
{
	CTempValue sum;
	sum = 1000;
	CTempValue sum = 1000;

	{
		char mystr[100] = "i love china";
		int result = calc(mystr);  //调用的是第一个
	}
	cout << "***********************" << endl;
	{
		string mystr = "i love china";
		int result = calc(mystr);  //调用的是第二个
	}
	cout << "***********************" << endl;
	{
		const string mystr = "i love china";
		int result = calc(mystr);  //调用的是第一个
	}
	cout << "***********************" << endl;
}

<3>函数返回对象的时候

CTempValue ts1(10, 20);
Double(ts1); //因为返回临时对象导致占用了一个拷贝构造函数和一个析构函数
第一个析构函数是tmp的,第二个析构函数是 系统构造要返回的临时对象的
CTempValue ts3 = Double(ts1);
CTempValue&& ts4 = Double(ts1); //临时对象是一种右值 临时对象被ts4接管了

Double()函数引起的消耗
CTempValue tmpm:会消耗一个构造函数和一个析构函数。
return tmp:产生临时对象,占用一个拷贝构造函数和析构函数。

在举一例:介绍知识点,类外运算符重载。
Time &Time::operator=(cosnt Time &tmpTime){… return *this;}

CTempValue Double(CTempValue& ts)
{
	//CTempValue tempm;
	//tempm.val1 = ts.val1 * 2;
	//tempm.val2 = ts.val2 * 2;
	//return tempm;
	return CTempValue(ts.val1 * 2, ts.val2 * 2);
}

CTempValue ts1(10, 20);
cout << "***********************" << endl;
//CTempValue ts3 = Double(ts1);
CTempValue&& ts4 = Double(ts1);

临时对象就是一种右值。

<4>类外的运算符重载之中的优化

class mynum
{
public:
	mynum()
	{
		cout << "调用了构造函数" << endl;
	}

	mynum(const mynum& t)
	{
		cout << "调用了拷贝构造函数" << endl;
	}

	virtual ~mynum()
	{
		cout << "调用了析构函数" << endl;
	}
public:
	int num1;
	int num2;
};

mynum operator+(mynum& tmpnum1, mynum& tmpnum2)
{
	mynum result;
	result.num1 = tmpnum1.num1 + tmpnum2.num1;
	result.num2 = tmpnum1.num2 + tmpnum2.num2;
	return result;
}

int main()
{
	mynum tm1;
	tm1.num1 = 10;
	tm1.num2 = 100;
	mynum tm2;
	tm2.num1 = 20;
	tm2.num2 = 200;
	mynum tm3 = tm1 + tm2;
}

优化后,少调用了一次拷贝构造函数,也少调用了一次析构函数。

class mynum
{
public:
	mynum(const mynum& t)
	{
		cout << "调用了拷贝构造函数" << endl;
	}
	mynum(int x = 0, int y = 0) : num1(x), num2(y)
	{
		cout << "调用了构造函数" << endl;
	}

	virtual ~mynum()
	{
		cout << "调用了析构函数" << endl;
	}
public:
	int num1;
	int num2;
};

mynum operator+(mynum& tmpnum1, mynum& tmpnum2)
{
	return mynum(tmpnum1.num1 + tmpnum2.num1, tmpnum1.num2 + tmpnum2.num2);
}

int main()
{
	mynum tm1;
	tm1.num1 = 10;
	tm1.num2 = 100;
	mynum tm2;
	tm2.num1 = 20;
	tm2.num2 = 200;
	mynum tm3 = tm1 + tm2;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值