两个方向的转换
设计一个分数的类,就是分子除以分母,返回的是double类型。所以在这个类的调用地方转换成double类型。
class Fraction
{
public :
Fraction(int num, int den=1)
: m_numerator(num), m_denominator(den) { }
operator double() const {
return (double) (m_numerator/m_denominator);
Fraction operator+(const Fraction& f) {
return Fraction(......);
}
private:
int m_denominator;
int m_numerator;
}
Fraction f(3,5);
double d=4+f;
这里面重点是operator的函数,返回类型不用写。
总结下:
1、没有返回值,返回类型在重载的名称中
2、没有参数
3、是const的,分子和分母是不变的
在使用的时候,编译器先找+号的重载函数,如果有重载的+第一个参数是int或float,第二个是Fraction。如果没有,再看能不能将f转换成double类型。
转换函数可以写多个,也不一定是基本类型,根据需要来定义。
对于有operator+的时候:
Fraction d2=f+4;
编译器会先找operator+,找到了,但是参数不配,编译器会将4转换成Fraction类型。
如果double()和operator+都有,连个都可以,编译器不知道该走哪个会报错ambiguous。
explicit
当构造函数前面加上expilcit就是告诉编译器,不要进行类型转换,要按照类的设计进行,这样d2=f+4 就不能转过去了。编译器会报错:conversion from ‘double’ to ‘Fraction’ requestion。
这个关键字大多是用在构造函数的前面。
explicit Fraction(int num, int den=1)
: m_numerator(num), m_denominator(den) { }
标准库中的转换代码:
template<class Alloc>
class vector<bool, Alloc>
{
public:
typedef __bit_reference reference;
protected:
reference operator[](size_type n) {
return *(begin() + difference_type(n));
}
...
struct __bit_reference {
unsigned int* p;
unsigned int mask;
...
public:
operator bool() const {return !(!(*p&mask));
...
这个设计手法叫做:代理,是一种设计模式,本来应该operator[]传回的是bool,但是返回的是reference.