Effective C++ 第三版 [条款24:隐喻类型转换的函数应该是个non-member]
原创
©著作权归作者所有:来自51CTO博客作者运妙心藏的原创作品,请联系作者获取转载授权,否则将追究法律责任
条款24:当一个类需要类型转换时,应使用 non-member 函数
例如:一个有理数类,想支持诸如加法、乘法等,是使用member 函数,还是使用 non-member 函数,还是使用 friend non-member 函数呢?
1,使用成员函数(member function)时
#include <iostream>
using namespace std;
class Rational {
public:
Rational(int num = 0, int den = 1) : numerator(num), denominator(den) {}
// member function
const Rational operator*(const Rational& rhs) const {
return Rational(numerator * rhs.numerator, denominator * rhs.denominator);
}
void print() const{
cout << numerator << "/" << denominator << endl;
}
int getNum() const { return numerator; }
int getDen() const { return denominator; }
private:
int numerator;
int denominator;
};
int main()
{
Rational oe(1, 8);
Rational oh(1, 2);
// success
Rational result = oe * oh;
result.print(); // (1,8) * (1,2) = (1, 16)
// success
result = oe * 2;
result.print(); // (1,8) * (2,1) = (2, 8)
// 这里2 进行了隐性转换
// Rational temp(2);>> temp(2,1)
// result = oe * temp;
// error
// result = 2 * oe;
// error C2677: 二进制“*”: 没有找到接受“Rational”类型的全局运算符(或没有可接受的转换)
system("pause");
return 0;
}
// output
1/16
2/8
2,使用非成员函数(non-member function)时
#include <iostream>
using namespace std;
class Rational {
public:
Rational(int num = 0, int den = 1) : numerator(num), denominator(den) {}
void print() const{
cout << numerator << "/" << denominator << endl;
}
int getNum() const { return numerator; }
int getDen() const { return denominator; }
private:
int numerator;
int denominator;
};
// non-member function
const Rational operator*(const Rational& lhs, const Rational& rhs) {
return Rational(lhs.getNum() * rhs.getNum(), lhs.getDen() * rhs.getDen());
}
int main()
{
Rational oe(1, 8);
Rational oh(1, 2);
// success
Rational result = oe * oh;
result.print(); // (1,8) * (1,2) = (1, 16)
// success
result = oe * 2;
result.print(); // (1,8) * (2,1) = (2, 8)
// 这里2 进行了隐性转换
// Rational temp(2);>> temp(2,1)
// result = oe * temp;
// success
result = 2 * oe;
result.print(); // (2,1) * (1,8) = (2, 8)
// 这里2 进行了隐性转换
// Rational temp(2);>> temp(2,1)
// result = temp * oe;
system("pause");
return 0;
}
// output
1/16
2/8
2/8
3,友元
本例而言是否定的,
结论:
只有当参数被列于参数列内(parameter list)时,参数才会是隐式类型转换的合格参与者。
如果你需要为某个函数的所有参数(包括被this指针所指的那个隐喻参数)进行类型转换,那个这个函数必须是个non-member