(一三〇)有关返回对象的说明

当函数/成员函数,返回对象时,有几种返回方式:

①返回指向对象的引用(例如String& operator=(xx,xx));

 

②返回被const限定的指向对象的引用(例如const String& operator=(xx,xx));

 

③返回const对象(这个之前没有遇介绍过)。

 

④返回对象(一般返回的不是类对象,而是类中的某一个数据对象。如果返回类对象的话,会调用复制构造函数——因为创建的是一个副本);

 

 

返回指向const对象的引用:

因为指向const对象,因此,对象不能被修改。

①假如调用的是const对象,那么应该在参数列表的括号后,加上const进行限定;

②假如是const对象作为参数,那么参数应该加上const表示限定;

 

并且,无论是哪种情况,函数名前必须加入const,因为返回值是const对象的引用。只有加了const才能限制返回值不作为左值。

 

其格式大致如下:

情况①

const String& String::函数名(参数列表)const

{

...

}

第一个const指返回值,第二个const指调用成员函数的对象

 

情况②

const String& 函数名(const String & 对象)

{

...

}

第一个const指返回值,第二个const指传递对象的引用

 

 

如果面向两种都可以用,那么则综合起来:

情况③

const String& 函数名(const String & 对象)const

{

...

}

第一个const指返回值,第二个const指传递对象的引用,第三个const指调用函数的对象。

 

 

 

返回指向非const对象的引用:

两种比较常见的返回非const引用的对象:

①赋值运算符重载(例如 =,但是+-*/ %这五个一般不会返回引用,会返回对象的引用);

 

②重载与ostream类、istream类一起使用的<<或>>运算符(为了能连续cout<<对象a<<对象b这样,必须返回);

 

 

对于①,返回非const对象的引用,可以避免创造一个副本来传递,节约内存,提高效率。

 

对于②,必须返回其引用(例如ostream&),原因在于只有这样,才能做到连续使用<<运算符来连接多个对象或者其他。

 

而对于=来说,返回对象的引用,可以进行连续赋值。例如a=b=c。

 

函数一般为:

Man& Man::operator=(const Man&n)	//调用的是被赋值的对象,隐式传递给函数
{
	if (this == &n) return *this;	//用于自己赋值给自己,判断地址的原因在于对象==对象需要运算符重载
	a = n.a;	//相等
	len = n.len;	//自然也相等
	delete[]b;	//因为已经初始化过了,新的长度不确定,因此要delete[]掉老的再重新申请动态内存
	b = new char[len + 1];	//new
	strcpy_s(b, len + 1, n.b);	//复制
	return *this;	//返回对象,*this表示当前对象
}

 

 

 

 

返回对象(函数内对象的副本):

假如返回的是函数内声明的对象,那么在函数结束时,这个对象将被执行析构函数,因此,只能返回其副本。例如Man Man::get();  使用的是Man而不是Man&,便表示的是返回对象。

 

返回对象其原理已知,跟普通函数返回基本类型、指针、结构一样。在return时,创建一个副本(调用复制构造函数),然后把副本放在寄存器,再将副本赋值给其。

 

一般是面对算数运算符(+-*/%)时使用。在函数内创建一个对象,然后把结果赋值给这个对象的各个成员,再将这个对象返回。

 

假如对象c=对象a+对象b。那么完成这行代码,

①执行一次返回对象的加法运算符重载函数

②在运算符重载函数的return语句,调用复制构造函数创建副本;

③再执行一次赋值运算符重载(假如是新对象初始化的话,改为执行复制构造函数)。

 

函数一般为:

Man Man::operator+(const Man n)	//两个对象相加并返回对象
{
Man c;	//创建对象c
c.a = a + n.a;	//c的a=两个对象a的和
delete[]c.b;	//删除c的b(因为之前new过)
c.len = len + n.len;	//c的字符串长度等于2个字符串长度之和(因为要将两个字符串拼起来)
c.b = new char[c.len + 1];	//c要new一个比字符串长1的内存(因为要留给空字符一个位置)
strcpy_s(c.b, len + 1, b);	//之所以要len+1,应该是要将空字符复制进去,反正用len不行
strcpy_s(c.b + len, n.len+1, n.b);	//复制第二段字符
return c;	//返回对象c,调用一次复制构造函数
}


 

main函数:

Man a(1,"abc");
Man b(2,"def");
Man c = a + b;	//调用复制构造函数
Man d;
d = b + a;	//调用赋值运算符重载
c.show();
d.show();


 

显示:

3,abcdef,6

3,defabc,6

 

 

效果是结果等于相加的两个各个数据成员之和(字符串则是将字符串拼在一起)。

 

 

 

 

 

返回const对象:

返回const对象的意义在于,避免让返回值成为左值。

例如,int a、bc;那么a=b+c是成立的,而a+b=c这样的算术式是不成立的。

 

然而,假如有Man operator+()这样的类重载函数,那么a+b=c这样的算术式是成立的。原因在于,a+b返回一个临时对象(根据运算符重载的函数定义,并且会调用复制构造函数创建临时对象),此时,是可以将c的值赋值给这个临时对象的(虽然并没有意义)。

 

因此,可以使用cosnt Man operator+(),这样的话,由于返回值被const限定,因此不能成为左值。于是,a+b=c这样的等式便不能使用了。

 

 

 


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值