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

来源:互联网 发布:淘宝摇一摇在哪 编辑:程序博客网 时间:2024/06/03 12:29

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

①返回指向对象的引用(例如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];//newstrcpy_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;//创建对象cc.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
原创粉丝点击