effective cpp小结条款21~40

条款21

在栈上创建对象

const Rational& operartor* (const Rational& lhs, const Rational& rhs) {
     
	Rational result(lhs.n * rhs.n, lhs.d * rhs.d);
	return result;//错误代码!
}

result是个local对象,在函数退出前就被销毁了

在堆上创建对象

const Rational& operartor* (const Rational& lhs, const Rational& rhs) {
     
	Rational * result = new Rational(lhs.n * rhs.n, lhs.d * rhs.d);//更糟糕的代码
	return result;
}
Rational w, x, y, z;
w = x * y * z;

这一句调用了两次operator*,因为使用了两次new,也就需要两次delete。但却没有合理的方法让operator* 使用者进行那些delete调用,因为没有合理的办法让他们取得operator*返回的引用背后隐藏的那个指针。将会导致资源泄漏。

让operator*返回的引用指向一个被定义在函数内部的static 对象

const Rational& operartor* (const Rational& lhs, const Rational& rhs) {
     
	static Rational result;
	result = ...;
	return result;
}

//当执行下面的语句
bool operator==(const Rational& lhs, const Rational& rhs);
Rational a, b, c, d;
if ((a * b) == (c * d)) {
     
	//...			//总是会执行这一局
}
else {
     
	//...
}

两次operator* 调用的确各自改变了static Rational对象值,但是由于他们返回的都是reference, 因此调用端看到的永远是static Rational对象的“现值”。

总结:

  • 别返回对象的引用

条款22

将成员变量声明为private,就是隐藏成员变量,也就是封装他们,只有成员函数可以改变他们
public意味着不封装,不封装意味着不可改变,特别是对被广泛使用的classes而言。
protected成员变量就像public成员变量一样缺乏封装性。

条款23

宁以non-member、non-friend替换member函数

你可能感兴趣的:(effective,c++)