Effective C++之条款21、22

条款21:必须返回对象时,别妄想返回其reference

    考虑一个用以表现有理数的class,内涵一个函数用来计算两个有理数的乘积:

class Rational {
public: 
	Rational(int numerator = 0, int denominator = 1);
	...
private:
	int n, d;
friend
	const Rational operator* (const Rational & lhs, const Rational& rhs);
};

    上述版本的operator*是以by-value方式返回计算结果的,如果改成reference呢?由于reference指向已有的对象,所以我们需要先创建对象。

const Rational& operator* (const Rational& lhs, const Rational& rhs) {
	Rational result(lhs.n * lhs.n, lhs.d * rhs.d);   //糟糕的代码
	return result;
}

    result是一个local对象,在对象退出函数之前会被销毁。因此它返回的reference指向一个已经被销毁的对象。于是,我们考虑在heap内构造一个对象,然后返reference指向它。Heap-based对象有new创建。

const Rational& operator* (const Rational& lhs, const Rational& rhs) {
	Rational* result = new Rational(lhs.n * rhs.n, lhs.d * rhs.d);
	return *result;
}

    new分配的内存,在不需要的时候,我们需要调用delete对他进行释放。

Rational w, x, y, z;
w = x * y * z;              //与operator* (operator*(x, y), z)相同

    这里,同一个语句内调用了两次operator*,因而两次使用new,也就需要两次delete。但却没有办法取得operator*返回的reference背后隐藏的指针。

一个必须返回新对象的函数的正确写法是:就让那个函数返回一个新的对象。

inline const Rational operator* (const Rational& lhs, const Rational& rhs) {
	return Rational(lhs.n * rhs.n, lhs.d * rhs.d);
}


条款22:将成员变量声明为private

请记住

  • 切记将成员变量声明为private。这可赋予客户访问数据的一致性、可细微划分访问控制、允诺约束条件获得保证,并提供class作者以充分的实现弹性。
  • protected并不比public更具封装性。
发布了33 篇原创文章 · 获赞 6 · 访问量 570

猜你喜欢

转载自blog.csdn.net/weixin_43519984/article/details/102565648