为何下面的程序类型转换函数和转换构造函数同时出现却没有出现二义性
#include<iostream.h>
class Complex
{
public:
Complex() //默认构造函数
{
real = 0;
imag = 0;
}
Complex(double r, double i) //初始化构造函数
{
real = r;
imag = i;
}
Complex(double d) //转换构造函数
{
real = d;
imag = 0;
}
operator double() //类型转换函数
{
return real;
}
friend Complex operator+ (Complex &c1, Complex &c2);
void display();
private:
double real;
double imag;
};
Complex operator+ (Complex &c1, Complex &c2)
{
return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
void Complex :: display()
{
cout << "(" << real << ", " << imag << ")" << endl;
}
int main()
{
Complex c1(3, 4), c4;
c4 = 5.0 + c1;
c4.display();
return 0;
}
[解决办法]
重载运算符这么写就有二义性了。
Complex operator+ (Complex const&c1, Complex const&c2)
{
return Complex(c1.real + c2.real, c1.imag + c2.imag);
}
原先没有二义性是因为 5.0 -> Complex 创建的是临时变量,后者根据标准不能绑定到 non-const lvalue reference 上,因此重载的版本根本就没进入 viable function set,overload resolution 进来的时候,只有一个 built-in double+double operator 可用了。
[解决办法]
一个是这两个函数的调用时机是不同的,下面的代码也是没有问题的
int main()
{
Complex c1(3, 4), c4;
//调用相应的构造函数构造对象
c4 = 5.0 + c1;
//上面这句话会比较的绕,但这句代码语法是正确的。因为你的重载+运算符设置为友元了,所以这里+号的左右两端都可以拿来当做参数,所以5.0会被拿出来尝试着创建一个类对象,发现确实是可以的,所以就会有一个临时对象出来.如果你的重载运算符+是成员函数形式,那么这么写就是错的,这个点在Effective C++中有讲到
c4.display();
return 0;
}
[解决办法]
c++会根据你的函数参数类型和数量来确定调用哪个版本的函数,事实上,在编译的时候,C++编译器会对你函数名进行名字粉粹,函数名加入每个函数的参数信息而形成一个新名字,只要参数有差别,就不会有二义性