1,成员函数和非成员函数最大的区别:前者可以是虚拟函数,而后者不可以。
2,关于成员函数和非成员函数:
例子:
class Rational
{
public:
Rational(int numerator = 0, int denominator = 1);
int numerator() const;
int denominator() const;
....
const Rational operator*(const Rational& rhs) const;
private:
...
};
注意下面的调用:
Rational oneEighth(1, 8);
Rational oneHalf(1, 2);
Rational result = oneHalf * oneEighth; // fine
result = result * oneEighth; // fine
result = oneHalf * 2; // fine
等价于:
result = oneHalf.operator*(2);//这里2发生了隐式转换
result = 2 * oneHalf; // error!
等价于:
result = 2.operator*(oneHalf); // error!
如果这么定义:
class Rational
{
public:
explicit Rational(int numerator = 0, int denominator = 1);
...
};
result = oneHalf * 2; // error
等价于:
result = oneHalf.operator*(2);//这里2发生了隐式转换
3,因为需要满足乘法的交换律,因此可以将operator*设置为非成员函数。
如:
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; // fine
result = 2 * oneFourth; // hooray, it works!
4,只要能够避免friend函数,就应该尽量避免。朋友带来的价值往往多于其价值。
5,总结:
(1)虚拟函数必须是成员函数。
(2)绝不要让operator>>和operator<<成员成员函数。
(3)只有非成员函数才能在其最左端参数身上实施型别转换。
(4)上述之外的每一种情况,都应该设计成员函数。
2,关于成员函数和非成员函数:
例子:
class Rational
{
public:
Rational(int numerator = 0, int denominator = 1);
int numerator() const;
int denominator() const;
....
const Rational operator*(const Rational& rhs) const;
private:
...
};
注意下面的调用:
Rational oneEighth(1, 8);
Rational oneHalf(1, 2);
Rational result = oneHalf * oneEighth; // fine
result = result * oneEighth; // fine
result = oneHalf * 2; // fine
等价于:
result = oneHalf.operator*(2);//这里2发生了隐式转换
result = 2 * oneHalf; // error!
等价于:
result = 2.operator*(oneHalf); // error!
如果这么定义:
class Rational
{
public:
explicit Rational(int numerator = 0, int denominator = 1);
...
};
result = oneHalf * 2; // error
等价于:
result = oneHalf.operator*(2);//这里2发生了隐式转换
3,因为需要满足乘法的交换律,因此可以将operator*设置为非成员函数。
如:
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; // fine
result = 2 * oneFourth; // hooray, it works!
4,只要能够避免friend函数,就应该尽量避免。朋友带来的价值往往多于其价值。
5,总结:
(1)虚拟函数必须是成员函数。
(2)绝不要让operator>>和operator<<成员成员函数。
(3)只有非成员函数才能在其最左端参数身上实施型别转换。
(4)上述之外的每一种情况,都应该设计成员函数。