104 C++ 临时性对象的整理和分析,详细探讨

根据之前的学习,我们知道,临时性对象的产生会消耗系统资源,我们学习临时性对象的整理和分析的 目的 就是怎么样 让这些 临时性对象少产生。

0.先来复习一下

产生临时对象的3中情况以及解决方案。

第一种:以值的方式给函数传递参数

class Teacher75 {
public:
	Teacher75() {
		cout << "Teacher75 构造函数" << this<< endl;
	}
	Teacher75(const Teacher75 & t) {
		this->m_age = t.m_age;
		cout << "Teacher75 copy 构造函数" << this<< "   t = " << &t<<endl;
	}
 
	Teacher75& operator=(const Teacher75 & t) {
		cout << "Teacher75 operator =  函数" << this<<endl;
		this->m_age = t.m_age;
		return *this;
	}
	int m_age;
};
 
//第一种:以值的方式给函数传递参数,这里参数是 Teacher75,
//当实参传递给形参的时候,会调用copy 构造函数,将实参传递copy 给形参 
void getTeacher75age(Teacher75 t) {
	cout << t.m_age << endl;
}
 
//第一种解决方案:
void getTeacher75agefix(Teacher75& t) {
	cout << t.m_age << endl;
}
void main() {
	Teacher75 t1;
	t1.m_age = 28;
	//第一种:以值的方式给函数传递参数
	getTeacher75age(t1);
 
	cout << "-----" << endl;
	Teacher75 t2;
	t2 = t1;
	cout << "---使用引用的方式传递函数参数---" << endl;
	getTeacher75agefix(t1);
}

第二种,函数返回临时对象的时候

//第二种,函数返回临时对象的时候
class Teacher76 {
public:
	Teacher76() {
		cout << "Teacher76 构造函数" << this << endl;
	}
	Teacher76(int age):m_age(age) {
		cout << "Teacher76 构造函数" << this << endl;
	}
	Teacher76(const Teacher76 & t) {
		this->m_age = t.m_age;
		cout << "Teacher76 copy 构造函数" << this << "   t = " << &t << endl;
	}
 
	Teacher76& operator=(const Teacher76 & t) {
		cout << "Teacher76 operator =  函数" << this << endl;
		this->m_age = t.m_age;
		return *this;
	}
	~Teacher76() {
		cout << "Teacher76 析构函数" << this << endl;
	}
	int m_age;
 
};
 
//问题,实际上是多一次 copy 构造函数调用
Teacher76 getTeacher76(){
	Teacher76 temp; //Teacher76 构造函数000000A584D8F564
	temp.m_age = 87;
	return temp; //Teacher76 copy 构造函数000000A584D8F784   t = 000000A584D8F564
}
 
//解决方案,在可以的case下 直接return 
Teacher76 getTeacher76fix() {
	return Teacher76(87); 
}
 
void main() {
	getTeacher76();
 
	//  Teacher76 构造函数000000A584D8F564  temp 构造函数被调用
	//	Teacher76 copy 构造函数000000A584D8F784   t = 000000A584D8F564   return 时,会调用copy 构造函数
	//  多了一个构造函数
	//	Teacher76 析构函数000000A584D8F564  // temp 被析构
	//	Teacher76 析构函数000000A584D8F784 //返回的copy出来的这个构造函数,没有接,因此也析构
 
	cout << "断点在这里" << endl;
 
	getTeacher76fix();
	//  Teacher76 构造函数00000085234FFB94
	//	Teacher76 析构函数00000085234FFB94
}

第三种 隐式类型转换

//第三种 隐式类型转换
int count(const string& source,char ch) {
	return 8;
}
void main() {
	char charshuzu[100] = "abcc";
	int ncount = count(charshuzu,'a');
	//这里调用为了能调用成功, charshuzu会被从char [100],隐式转换成 const string 。
 
	//这会有隐式转换发生。
 
	//改法:不要让C++编译器帮忙转,自己转。
	string mystr = "mnv";
	int ncount222 = count(mystr, 'a');
}

一。我们这里主要是研究一下,函数返回临时对象的情况,顺便研究一下,如果返回的是临时对象引用会怎么样

总结:返回的是对象,那么会有临时对象的产生,会调用 copy 构造。如果开发者自己正确的写了 copy函数(这里所谓正确的写了,是指的在有指针,或者引用的case 下,fix了浅拷贝问题),返回的对象是可以使用的。

但是如果返回的是 对象的引用,由于引用就是其本身,在函数结束的时候,就

//返回临时性对象 和 临时性对象 引用的 研究

class Teacher40{
public:
	Teacher40() {
		cout << "Teacher40 构造方法 this = " << this << endl;
	}

	~Teacher40() {
		cout << "Teacher40 析构方法 this = " << this << endl;
	}

	Teacher40(const Teacher40 &obj) {
		this->mage = obj.mage;
		cout << "Teacher40 copy gouzao 方法  this = " << this << "   obj = " << &obj << endl;
	}

	Teacher40 & operator=(Teacher40 &obj) {
		cout << "Teacher40 copy gouzao 方法   this = " << this << "   obj = " << &obj << endl;
		this->mage = obj.mage;
		return *this;
	}

	void print() {
		cout   << "   mage = "  << mage << " this = " << this <<  endl;
	}

	int mage;
};

Teacher40 getTeacher40() {
	return Teacher40();
}

Teacher40 getTeacher401() {
	Teacher40 tea; // 调用构造函数,tea这时候是0019FA2C
	return tea; //return 的时候,会生成一个临时对象0019FA60,然后调用copy gouzao 将 0019FA2C的值赋值给0019FA60 
				//return执行完毕后,出了 getTeacher401的作用域,则会0019FA2C ,析构。
				//那么这时候return 出去的就是一个临时对象 0019FA60
	//Teacher40 构造方法 this = 0019FA2C
	//	Teacher40 copy gouzao 方法  this = 0019FA60   obj = 0019FA2C
	//	Teacher40 析构方法 this = 0019FA2C
	//	Teacher40 析构方法 this = 0019FA60
	//  duandian
}

Teacher40& getTeacher40yinyong() {
	//return Teacher40();//build error。由于Teacher40()是一个右值,右值不能作为引用返回,
	Teacher40 tea;
	return tea;

	//Teacher40 构造方法 this = 0073FDE8
	//	Teacher40 析构方法 this = 0073FDE8
	//	duandian new
}

void  main41() {
	getTeacher401();//这一条的时候 0019FA60 临时对象没有人接,立即就析构了

	cout << "duandian" << endl;
}

void main42() {
	getTeacher40yinyong();
	cout << "duandian new" << endl;
}


Teacher40& getTeacher40yinyong2() {
	//return Teacher40();//build error。由于Teacher40()是一个右值,右值不能作为引用返回,
	Teacher40 tea;
	tea.mage = 98;
	return tea;

}
void main() {
	Teacher40 tea = getTeacher40yinyong2();
	cout << "tea.mage = " << tea.mage << endl;
	cout << "duandian new 1" << endl;

	//注意看的是:在返回局部变量引用的时候,局部变量会先析构,因此这么写mage不会被赋值为98
	//  Teacher40 构造方法 this = 038FFB68
	//	Teacher40 析构方法 this = 038FFB68
	//	Teacher40 copy gouzao 方法  this = 038FFC50   obj = 038FFB68
	//	tea.mage = 59767888
	//	duandian new 1
	//	Teacher40 析构方法 this = 038FFC50
}

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值