One argument是指:一个实参,但并不是值构造函数只有一个参数,例如:
#include <iostream>
class Fraction_one_argument
{
public:
//隐式构造函数
Fraction_one_argument(int num, int den = 1) : number(num), deno(den) {}
//重载+操作符
Fraction_one_argument operator +(const Fraction_one_argument& f)
{
std::cout << "重载+操作符" << std::endl;
return Fraction_one_argument(number * f.deno + f.number * deno, f.deno * deno);
}
public:
int number; //分子
int deno; //分母
};
隐式转换与转换函数的区别在于:隐式转换是将其他类型转化为拥有对应类型构造函数的对象类型,而转换函数是将自己转换为其他类型。如:
std::ostream& operator << (std::ostream& os, const Fraction_one_argument& f)
{
return os << f.number * 1.0 / f.deno;
}
int main()
{
Fraction_one_argument f1(3); //分数:3/1
//调用隐式构造函数,将4转化为Fraction_one_argument(4,1)
//再查找是否有对应类型的全局重载+
Fraction_one_argument f2 = f1 + 4; //重载操作符+
std::cout << f2 << std::endl; //7
return 0;
}
此时是将4---->Fraction_one_argument类型,调用了Fraction_one_argument的隐式构造函数,然后进行+操作时相当于两个Fraction_one_argument类型进行+操作,此时有两条路可以选:在全局重载+操作符(两个参数,类型都是Fraction_one_argument类型),或者在Fraction_one_argument类内重载+操作符(参数1个。编译器默认给加上this)。
但是:如果类中有了对应类型的转换函数,此时会因为有歧义(编译器不知道调用哪条路线而报错),事实上这两条路线有一条就可以,或者对其中一条路线使用explicit进行显式声明。
//显示构造函数
explicit Fraction_one_argument(int num, int den = 1) : number(num), deno(den) {}
//重载+操作符
Fraction_one_argument operator +(const Fraction_one_argument& f)
{
std::cout << "重载+操作符" << std::endl;
return Fraction_one_argument(number * f.deno + f.number * deno, f.deno * deno);
}
//转换函数
operator double() const {
return (double)(number*1.0)/deno;
}
此时显示声明构造函数,在上述main函数执行
Fraction_one_argument f2 = f1 + 4;
编译器将f1---->double,与4相加后无法将double类型转换为Fraction_one_argument类型报错。