# Effective C++ 2e Item19

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

private:
...
};

class Rational {
public:

...

const Rational operator*(const Rational& rhs) const;
};

（如果你不明白为什么这个函数以这种方式声明——返回一个const值而取一个const的引用作为它的参数——参考条款21-23。）

Rational oneEighth(1, 8);
Rational oneHalf(1, 2);

Rational result = oneHalf * oneEighth;   // 运行良好

result = result * oneEighth;             // 运行良好

result = oneHalf * 2;      // 运行良好

result = 2 * oneHalf;      // 出错!

result = oneHalf.operator*(2);      // 运行良好

result = 2.operator*(oneHalf);      // 出错!

result = operator*(2, oneHalf);      // 错误!

const Rational temp(2);      // 从2产生一个临时
// Rational对象

result = oneHalf * temp;     // 同oneHalf.operator*(temp);

class Rational {
public:
explicit Rational(int numerator = 0,     // 此构造函数为
int denominator = 1);  // explicit
...

const Rational operator*(const Rational& rhs) const;

...

};

result = oneHalf * 2;             // 错误!
result = 2 * oneHalf;             // 错误!

result = oneHalf.operator*(2);      // converts int -> Rational

result = 2.operator*(oneHalf);      // 不会转换
// int -> Rational

class Rational {

...                               // contains no operator*

};

// 在全局或某一名字空间声明，
// 参见条款M20了解为什么要这么做
const Rational operator*(const Rational& lhs,
const Rational& rhs)
{
return Rational(lhs.numerator() * rhs.numerator(),
lhs.denominator() * rhs.denominator());
}

Rational oneFourth(1, 4);
Rational result;

result = oneFourth * 2;           // 工作良好
result = 2 * oneFourth;           // 万岁, 它也工作了!

// 一个不正确地将operator>>和
// operator<<作为成员函数的类
class String {
public:
String(const char *value);

...

istream& operator>>(istream& input);
ostream& operator<<(ostream& output);

private:
char *data;
};

String s;

s >> cin;                   // 合法, 但
// 有违常规

s << cout;                  // 同上

istream& operator>>(istream& input, String& string)
{
delete [] string.data;

read from input into some memory, and make string.data
point to it

return input;
}

ostream& operator<<(ostream& output,
const String& string)
{
return output << string.data;
}

·虚函数必须是成员函数。如果f必须是虚函数，就让它成为C的成员函数。

·operator>>和operator<<决不能是成员函数。如果f是operator>>或operator<<，让f成为非成员函数。如果f还需要访问C的非公有成员，让f成为C的友元函数。

·只有非成员函数对最左边的参数进行类型转换。如果f需要对最左边的参数进行类型转换，让f成为非成员函数。如果f还需要访问C的非公有成员，让f成为C的友元函数。

·其它情况下都声明为成员函数。如果以上情况都不是，让f成为C的成员函数。

• 本文已收录于以下专栏：

举报原因： 您举报文章：Effective C++ 2e Item19 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)