【c++】返回类对象

函数返回值是一个类对象时,有以下几种选择:

1,返回对象或者对象的引用 2,它们是const的or not

1,返回对象的const引用,举例:

#include <iostream>
#include <cmath>

using namespace std;

class Complx {
private:
	double real;
	double imag;
public:
	Complx() {}   //构造函数
 	Complx(double r, double i): real(r), imag(i) {}//带参数的构造函数
	Complx  operator+(const Complx & c) const {//运算符重载
		return Complx(real + c.real, imag + c.imag);
	}
	Complx & operator=(const Complx &c;) {//第一个&表明返回值是计算结果的引用,第二个&表明使用c的引用,const表明不会改变c
		real = c.real;
		imag = c.imag;
		return *this;//返回对象的引用(如果是前面不是complex &而是complex,那么返回的就是对象的拷贝)
	}

	friend ostream& operator<<(ostream &os;, const Complx &c;);
	double size() const {//const修饰成员函数,表示该函数不能改动类的内容
		return sqrt(real*real + imag*imag);
	}
};

ostream & operator<<(ostream &os;, const Complx & c) {//conventional的<<操作符重载,用于输出用户自定义的类对象。就按照这个格式写:函数定义为类的友元函数,第一个参数定义为ostream类对象的引用
	os << "(" << c.real << "," << c.imag << ")";//第二个实参是用户自己定义的要输出的类对象的引用
	return os;//返回值是参数一
}

/*方式1,直接返回类对象
Complx Maximum(const Complx &c1;, const Complx &c2;) {
	
	if (c1.size() > c2.size()) 
		return c1;
	else
		return c2;
}
*/
//方式二,返回类对象的引用
const Complx & Maximum(const Complx &c1;, const Complx &c2;) {
	
	if (c1.size() > c2.size()) 
		return c1;
	else
		return c2;
}

int main( ) 
{ 
	Complx c1(10,30);
	Complx c2(13,25);
	Complx mx = Maximum (c1,c2);

	cout << " c1 = " << c1 << endl;
	cout << " c2 = " << c2 << endl;
	cout << "Maximum(c1,c2) = " << mx << endl;

	Complx c3 (20,40);
	Complx c4,c5;
	c5 = c4 = c3;

	cout << c4 << " got its value from c3" << endl;

	Complx c6 = c1 + c2;
	cout << " c6 (c1+c2) = " << c6 << endl;

	Complx c7;
	c1 + c2 = c7;
	return 0; 
}

得到以下结果:

 c1 = (10,30)
 c2 = (13,25)
 Maximum(c1,c2) = (10,30)
(20,40) got its value from c3
 c6 (c1+c2) = (23,55)

上面的方式12都可以,我们用的方式2.因为用引用省去了拷贝(即调用拷贝构造函数)的过程。(返回值类型是引用:那就返回对象的引用;返回值类型直接是类对象:返回的是对象的副本。所以用引用会效率高一些,不用拷贝)另外,因为我们的参数使用的是const型的引用,所以返回值也是const型的,以匹配。(这句话我没懂,为什么返回值非得匹配呢)

2,返回对象的非cons引用

这种用法常见于重载赋值操作符=,和流操作符<<,重载它们,其实返回对象或对象引用都行,引用好一些。关于这部分,建议复习一下操作符重载。

比如链式的赋值:

Complx c3 (20,40);
Complx c4,c5;
c5 = c4 = c3;

c4=c3也就是c4.operator=(c3)也就是operator=(complx &c4,complx &c3)也就是

complx &operator=(complx &c4,complx &c3)

{c4.real=c3.real;

扫描二维码关注公众号,回复: 1866853 查看本文章

c4.img=c3.img;

return c4;}

被赋给c5。这个例子里返回值类型就不是const的,因为c4是要被改变的。

链式的输出:

cout << c4 << " got its value from c3" << endl; 
cout<<c4等价于operator<<(cout,c4),它的返回值是cout的引用,也是非const型的,以便以后它的值再被改变。这里,返回值类型不能直接是对象,因为这样要调用拷贝构造函数,但是ostream类没有public的拷贝构造函数。


3,返回类对象

如果返回的对象是所调用函数的局部对象,那它就不应该被以引用的方式返回,因为在这个函数调用结束的时候局部对象会自动消除,所以不用我们管。也因此,我们绝对不能返回一个局部对象的引用,因为函数调用完的时候它已经不存在了。

举例:

const Complx &complxReturn;(const Complx & c) {
		Complx complxObj = c;
		return complxObj;
}

这里complxObj就是一个局部变量,我们想得到它,只能返回它的拷贝,不能返回引用。

4,返回const类对象

通常,不建议用const修饰函数的返回值类型为某个对象或对某个对象引用的情况。原因如下:如果返回值为某个对象为constconst A test = A 实例)或某个对象的引用为constconst A& test = A实例) ,则返回值具有const属性,则返回实例只能访问类A中的公有(保护)数据成员和const成员函数,并且不允许对其进行赋值操作,这在一般情况下很少用到。

总结:

1,如果函数返回的是局部变量,那么返回值类型不能是引用或指针。

2,如果函数返回的是类对象,但是该类没有public的拷贝构造函数,比如ostream类,那就返回引用。

3,有的函数,比如重载的=,可以返回对象也可以返回引用,引用比较好,因为效率高。

再总结:除了返回局部对象,一般都是返回引用。

(写的比较乱,还会再改)

猜你喜欢

转载自blog.csdn.net/ethan_guo/article/details/80720715
今日推荐