c++ 必须返回对象时,别妄想返回其 reference(引用)

上一章 说了 尽量以传引用的方式 代替 传值
上一篇

本篇说一下 有些地方是不能返回引用的 !
参考 effective c++ 21条款

自从上一篇说了 传const引用要比传值效率高多了
我们就想在所有的地方都使用 pass -by - reference ,保证纯度
我们就犯了致命的错误 传递一些 reference 指向一些并不存在的对象 。

看个类

class Rational
{
public:
	Rational(int numerator = 0, int denominator = 1);

private:
	int numerator;
	int denominator;

	friend const Rational operator* (const Rational& lhs, const Rational& rhs);
};

这个类 operator* 以传值的方式 返回一个 Rational 对象
既然我们知道了 传值带来的 构造和析构的代价 我们就改为 传引用的方式 看下面

Rational a(1,2);
Rational b(3,4);

Rational c = a*b;
 

既然接收的c 是个对象 那我们的函数实现就要创建一个对象
有两种方式
1 .创建局部对象 在 stack 上
2. 创建heap 对象 在 heap上

先看第一种的实现

	friend const Rational& operator* (const Rational& lhs, const Rational& rhs)
	{
		Rational result(lhs.numerator * rhs.numerator,
			lhs.denominator * rhs.denominator);

		return result;
	}

你可以拒绝这种写法
因为

  1. reference 不能指向一个已经销毁的对象 局部对象 这个是很错误的决定
  2. 里面还是实例化了一个对象 还是调用了构造,不是我们想要的效果

那我们实现第二种写法在 堆heap上创建对象

	friend const Rational& operator* (const Rational& lhs, const Rational& rhs)
	{
		Rational *result = new Rational(lhs.numerator * rhs.numerator,
										lhs.denominator * rhs.denominator);

		return *result;
	}

还是避免不了 一个构造函数的代价 但是解决了 引用指向的对象是个已经销毁的对象了

又出现了个新问题? 你new 的谁给你delete ?
这样就造成内存泄露了啊

你说可以delete 引用就可以了
看下面
在这里插入图片描述
在这里插入图片描述
把上面返回引用 改成 下面的返回指针倒是可以
在这里插入图片描述

Ration w,x,y,z;

w = x* y*z;

上面代码 调用两次 new 你怎么delete ??

所以这两张写法都不行

一个必须返回新对象的代码可以写成下面的形式

	friend inline const Rational operator* (const Rational& lhs, const Rational& rhs)
	{
		return Rational(lhs.numerator * rhs.numerator,
			lhs.denominator * rhs.denominator);
	}

返回了一个新对象 ,然而还是没有避免 构造的代价

注意:
当我们必须在 返回一个reference 和 返回一个 object 之间选择时
你的工作就是挑选出正确的方法,至于效率是必须承受的

记住:
千万不要返回一个 指针pointer 或者 引用 reference 指向一个 local 局部对象
或者返回一个引用指向一个heap的对象

发布了178 篇原创文章 · 获赞 396 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/weixin_42837024/article/details/105071974
今日推荐