第一步分析:
Complex c1(1,2);
Complex c2;
c2 = c1 + 2;
当你写好算术表达式之后,系统会自动判断准备到底执行调用下面哪种operator+
一个是 自定义类型 Complex + Complex的 +运算符重载operator+
一个是 内置的基本类型 int + int 的 +运算符重载operator+
真理 ->>> 记住一定是先有调用,才会发生隐式转换。
看是提供了 Complex + Complex的 +运算符重载operator+
还是提供了 int + int 的 +运算符重载operator+
如果存在Complex + Complex的 +运算符重载operator+。
那么之后系统会判断调用Complex+Complex的operator+的方案是否可以,也就是此时再判断(实参到形参的)类型转换是否能成功。(这句话印证了真理)
如果此时也提供了int->Complex的单参转换构造,那么系统会认为此路可行。
如果此时并没有提供int->Complex的单参转换构造,那么系统会认为此路不通。则不会选择执行这个。
如果存在内置int + int的 +运算符重载operator+。
那么之后系统会判断调用c1.operator+(Complex &)的方案是否可以,也就是此时再判断(实参到形参的)类型转换是否能成功。(这句话印证了超级对的真理)
如果此时也提供了Complex->int的operator int操作符类型转换函数,那么系统会认为此路可行。
如果此时并没有提供Complex->int的operator int操作符类型转换函数,那么系统会认为此路不通。则不会选择执行这个。
如果同时存在上面两个。且上面两个路都能通过
那么系统就会报错,歧义。系统不知道到底选哪个。
因为只有自定义类型与基本类型之间的运算才会容易闹这个歧义的屁事。
第二步分析:
所以其实 只要写上两个类型转换功能函数, 现在那么就是已经在本类中支持了两个方向转,基本类型->本对象类型, 本对象类型->基本类型。。能不能实现顺序不同的表达式的卡壳报错地方并不在与,主要还是operator运算符重载函数的调用。在这方面理解必须要扎实到位。
单参转换构造函数 可以通过int->Complex,只能来单独实现c1+2表达式 ,不能单独实现2+c1表达式,因为前提是调用了类内的Complex+Complex的operator+。如果想通过int->Complex,来单独实现2+c1表达式 或 同时实现c1+2 和2+c1表达式。 那就把Complex+Complex的operator+,设为全局函数,且设为Complex类的友元即可。
类型转换操作符函数,可以通过Complex->int,来单独实现c1+2。 前提是调用了全局的内置+。
类型转换操作符函数,既可以通过Complex->int 来同时实现c1+2表达式和2+c1表达式,即两个表达式功能同时可存在。前提都是调用了全局的内置+
第三步着手验证:
————————————————————————————————————————————————————————
一.通过类型转换同时实现下面两行代码:
c2 = c1 + 5;
c2 = 5 + c1;
1. int转为Complex
#include <iostream>
using namespace std;
class Complex
{
friend Complex operator+(const Complex & c1,const Complex & c2);
public:
Complex()
{
cout<<"Complex()"<<endl;
this->_x = 0;
this->_y = 0;
}
Complex(int x,int y)
:_x(x),_y(y)
{
cout<<"Complex(int x,int y)"<<endl;
}
Complex(const Complex& c2)
:_x(c2._x),_y(c2._y)
{
cout<<"Complex(const Complex& c2)"<<endl;
}
#if 1
Complex operator+(const Complex & c2)
{
cout<<"Complex operator+(const Complex & c2)"<<endl;
Complex temp(this->_x+c2._x,this->_y+c2._y);
return temp;
}
#endif
Complex& operator=(const Complex & c2)
{
this->_x = c2._x;
this->_y = c2._y;
return *this;
}
#if 1//int -> Complex
Complex(int x)
:_x(x),_y(0)
{
cout<<"Complex(int x)"<<endl;
}
#endif
#if 0//Complex ->int
operator int()
{
cout<<"operator int()"<<endl;
return _x;
}
#endif
private:
int _x;
int _y;
};
Complex operator+(const Complex & c1,const Complex & c2)
{
cout<<"Complex operator+(const Complex & c2)"<<endl;
Complex temp(c1._x+c2._x,c2._x+c2._y);
return temp;
}
int main()
{
Complex c1(1,2);
Complex c2;
c2 = c1 + 5;//->调用Complex::operator+(const Complex & c2) -> int转为Complex
c2 = 5 + c1;//->调用Complex operator+(const Complex & c1,const Complex & c2) -> int转为Complex
return 0;
}
2.Complex转为int, 但是这样子不好,因为必须不能自实现自定义的operator+,必须关闭此路。
#include <iostream>
using namespace std;
class Complex
{
public:
Complex()
{
cout<<"Complex()"<<endl;
this->_x = 0;
this->_y = 0;
}
Complex(int x,int y)
:_x(x),_y(y)
{
cout<<"Complex(int x,int y)"<<endl;
}
Complex(const Complex& c2)
:_x(c2._x),_y(c2._y)
{
cout<<"Complex(const Complex& c2)"<<endl;
}
#if 0 //关掉此路之后才对
Complex operator+(const Complex & c2)
{
cout<<"Complex operator+(const Complex & c2)"<<endl;
Complex temp(this->_x+c2._x,this->_y+c2._y);
return temp;
}
#endif
Complex& operator=(const Complex & c2)
{
this->_x = c2._x;
this->_y = c2._y;
return *this;
}
#if 1//int -> Complex
Complex(int x)
:_x(x),_y(0)
{
cout<<"Complex(int x)"<<endl;
}
#endif
#if 1//Complex ->int
operator int()
{
cout<<"operator int()"<<endl;
return _x;
}
#endif
private:
int _x;
int _y;
};
int main()
{
Complex c1(1,2);
Complex c2;
c2 = c1 + 5;//->调用内置operator+(int ,int ) -> Complex转为int
c2 = 5 + c1;//->调用内置operator+(int ,int ) -> Complex转为int
return 0;
}
二.通过类型转换同时实现下面两行代码:
int value;
value = c1 + 5;
value = 5 + c1;
1..Complex转为int
#include <iostream>
using namespace std;
class Complex
{
public:
Complex()
{
cout<<"Complex()"<<endl;
this->_x = 0;
this->_y = 0;
}
Complex(int x,int y)
:_x(x),_y(y)
{
cout<<"Complex(int x,int y)"<<endl;
}
Complex(const Complex& c2)
:_x(c2._x),_y(c2._y)
{
cout<<"Complex(const Complex& c2)"<<endl;
}
#if 1
Complex operator+(const Complex & c2)
{
cout<<"Complex operator+(const Complex & c2)"<<endl;
Complex temp(this->_x+c2._x,this->_y+c2._y);
return temp;
}
#endif
Complex& operator=(const Complex & c2)
{
this->_x = c2._x;
this->_y = c2._y;
return *this;
}
#if 0//int -> Complex
Complex(int x)
:_x(x),_y(0)
{
cout<<"Complex(int x)"<<endl;
}
#endif
#if 1//Complex ->int
operator int()
{
cout<<"operator int()"<<endl;
return _x;
}
#endif
private:
int _x;
int _y;
};
int main()
{
Complex c1(1,2);
int value;
value = c1 + 5;//->调用内置operator+(int,int) -> Complex转为int
value = 5 + c1;//->调用内置operator+(int,int) -> Complex转为int
return 0;
}
2.int转为Complex 无法实现同时共存两个表达式,下面的代码编译不通过。 原因在于无法关闭内置operator+(int,int )这条路。目前不知怎么关闭。
//编译不通过。
#include <iostream>
using namespace std;
class Complex
{
friend Complex operator+(const Complex & c1,const Complex & c2);
public:
Complex()
{
cout<<"Complex()"<<endl;
this->_x = 0;
this->_y = 0;
}
Complex(int x,int y)
:_x(x),_y(y)
{
cout<<"Complex(int x,int y)"<<endl;
}
Complex(const Complex& c2)
:_x(c2._x),_y(c2._y)
{
cout<<"Complex(const Complex& c2)"<<endl;
}
#if 1
Complex operator+(const Complex & c2)
{
cout<<"Complex operator+(const Complex & c2)"<<endl;
Complex temp(this->_x+c2._x,this->_y+c2._y);
return temp;
}
#endif
Complex& operator=(const Complex & c2)
{
this->_x = c2._x;
this->_y = c2._y;
return *this;
}
#if 1//int -> Complex
Complex(int x)
:_x(x),_y(0)
{
cout<<"Complex(int x)"<<endl;
}
#endif
#if 1//Complex ->int
operator int()
{
cout<<"operator int()"<<endl;
return _x;
}
#endif
private:
int _x;
int _y;
};
Complex operator+(const Complex & c1,const Complex & c2)
{
cout<<"Complex operator+(const Complex & c2)"<<endl;
Complex temp(c1._x+c2._x,c2._x+c2._y);
return temp;
}
int main()
{
Complex c1(1,2);
int value;
value = c1 + 5;//->调用Complex::operator+(const Complex & c2) -> int转为Complex ->最后再转为int 赋给左值
value = 5 + c1;//->调用Complex operator+(const Complex & c1,const Complex & c2) -> int转为Complex ->最后再转为int 赋给左值
return 0;
}
三.通过类型转换同时实现下面两行代码:
int value;
c2 = c1 + 5;
value = 5 + c1;
#include <iostream>
using namespace std;
class Complex
{
public:
Complex()
{
cout<<"Complex()"<<endl;
this->_x = 0;
this->_y = 0;
}
Complex(int x,int y)
:_x(x),_y(y)
{
cout<<"Complex(int x,int y)"<<endl;
}
Complex(const Complex& c2)
:_x(c2._x),_y(c2._y)
{
cout<<"Complex(const Complex& c2)"<<endl;
}
#if 0 //必须关掉此路
Complex operator+(const Complex & c2)
{
cout<<"Complex operator+(const Complex & c2)"<<endl;
Complex temp(this->_x+c2._x,this->_y+c2._y);
return temp;
}
#endif
Complex& operator=(const Complex & c2)
{
this->_x = c2._x;
this->_y = c2._y;
return *this;
}
#if 1//int -> Complex
Complex(int x)
:_x(x),_y(0)
{
cout<<"Complex(int x)"<<endl;
}
#endif
#if 1//Complex ->int
operator int()
{
cout<<"operator int()"<<endl;
return _x;
}
#endif
private:
int _x;
int _y;
};
int main()
{
Complex c1(1,2);
Complex c2;
int value;
//下面俩代码=右边都是Complex转为int ,然后第一个再转为Complex.
c2 = c1 + 5;//必须关掉Complex operator+(const Complex & c2)此路,才能与下面表达式代码共存
value = 5 + c1;
return 0;
}
四。通过类型转换同时实现下面两行代码:
Complex c1(1,2);
Complex c2;
int value;
c2 = 5 + c1;
value = c1 + 5;
懒得去试写了。感觉有点无意义。
关于实现类型转换时谨记两点:
//1.感觉最后还是加explict,来只允许强制才用的更舒服。所以还是别让系统自动选路了,省的老引发歧义,导致各种不能同时实现的问题。
//2.切务必要遵循目的语义,不要像上面那些的试验乱来。先确定语义再搞实现。确定想让哪个转哪个,而不是追求表达式代码共存(一效率低,二可能无意义)。