之前看《effective c++》的时候,对这一部分印象比较深刻,虽然读的时候有写笔记,但是现在还是写下来我对这一部分理解。详细的内容可以看条款19:分清成员函数,非成员函数和友元。
条款19的结论如下:
只有在下列情况下,让函数f成为类c的非成员函数。其余情况,f都声明为c的成员函数。
(1)operator>>和operator<<决不能是成员函数,如果f是operator>>或operator<<,让f成为非成员函数。如果f还要访问c的非公有成员,让f成为c的友元函数。
(2)如果f需要对最左边的参数进行类型转换,让f成为非成员函数。如果f还要访问c的非公有成员,让f成为c的友元函数。
照着书上的内容写了两个很简单的例子:
(1)关于operator>>和operator<<
假如operator>>和operator<<是类的成员函数,以string类为例,在类中会有这样的定义
class string
{
private:
char* m_pData;
public:
istream& operator>>(istream& input);
ostream& operator<<(ostream& output);
}
则在调用的时候,会出现这样的形式
string str;
str>>cin; 等同于str.operator>>(cin);
str<<cout; 等同于str.operator<<(cout);
虽然这样是合法的,编译器并不会报错,但是看起来并不是很合理。因此需要将operator>>和operator<<声明为非成员函数。
String.h
String.cpp
main.cpp
(2)需要对最左边的参数进行类型转换
有一个有理数的类,假设opertor*是成员函数
class Rational
{
private:
int numerator;
int denominator;
public:
Rational operator*(const Rational& r);
};
则
Rational result = r * 2;,等同于 r.operator*(2),编译器对2进行了强制类型转换,可以进行运算
而
Rational result = 2 * r,等同于2.operator*(r),对2来说,没有operator*这个成员函数。就不可以进行运算了,“编译器会去搜索operator * (2, r)这样的非成员函数”(书上),但是搜索失败
rational.h
rational.cpp
main.cpp