C++中返回值为对象详解

版权声明:博主原创文章,转载请注明来源。 https://blog.csdn.net/somehow1002/article/details/50206589

以下以一个例子说明C++中返回值为对象的过程详解。

#include <iostream>
using namespace std;
//建一个Test类
class Test
{
public:
	Test()
	{
		a = 0;
		b = 0;
		cout << "无参构造函数被调用了" << endl;
	}
	Test(int aa, int bb)
	{
		a = aa;
		b = bb;
		cout << "有参构造函数被调用了" << endl;
	}
	Test(const Test& t)
	{
		a = t.a;
		b = t.b;
		cout << "复制构造函数被调用了" << endl;
	}
	void print()
	{
		cout << "a:" << a << endl << "b:" << b << endl;
	}
	~Test()
	{
		cout << "析构函数被调用了" << endl;
	}
private:
	int a;
	int b;
};

//以下为几个方便说明的操作函数
Test g()
{
	Test tt(11, 22);
	return tt;
}
void play1()
{
	g();
}
void play2()
{
	Test t1 = g();
	t1.print();
}
void play3()
{
	Test t2(3,4);
	t2.print();
	t2 = g();
	t2.print();
}

//主函数
int main()
{
	play1();
调用此句时,g()被调用,首先在g()函数中创建一个tt对象,随后调用复制构造函数,由tt对象给产生的匿名对象初始化,随后tt对象被析构,在play1()中,因为g()中的匿名对象并没有给任何对象初始化或复制,因此在play1()中,又会调用析构函数将当做参数传回来的匿名对象析构掉,因此结果为:



play2();
调用此句时,g()调用部分与上例相似,不同的是g()传回来的参数给t1这个对象初始化,编译器在处理这句话时并没有创建一个新的对象来接受g()返回来的匿名对象的值,而是采取了优化,直接将这个匿名对象扶正,给其一个名字叫t1,所以匿名对象没有析构,随后可以打印t1(),当play2()函数结束时,才会将t1析构掉,结果如下

play3();

play3()和play2()的区别在于,g()返回值(即匿名对象)并没有给一个对象初始化,而是赋值!!!t2这个对象已经存在了,有了确定的内存空间,所以匿名对象不会扶正,匿名对象的作用是给这个t2对象重新赋值,t2=g()这句话会调用赋值构造函数(而不是复制构造函数),因此结果如下

system("pause");
	return 0;
}

以上程序运行结果跑在Visual Studio2015Debug环境下,如果跑在Release环境下的话结果会不同,Debug方便调试,Release是发布版本,进行了一系列的优化改进

阅读更多

扫码向博主提问

somehow1002

非学,无以致疑;非问,无以广识
  • 擅长领域:
  • PHP
  • Java
  • MySQL
去开通我的Chat快问
换一批

没有更多推荐了,返回首页