类的转换构造函数与类的转换运算符重载函数是互逆的。(例3中的Test(int a = 0)是将int类型的数据转换构造成Test类对象,而operator int()则是将Test类对象转换成int类型数据)
但是当他们是出现在两个不同的类中,对于一个类对象转换来说,同时拥有两种近似的转换途径的时候,多义性的问题就暴露出来,导致编译出错。
下例就是这个状态:
//程序作者:管宁 //站点:www.cndev-lab.com //所有稿件均有版权,如要转载,请务必著名出处和作者 #include <iostream> using namespace std; class B; class A { public: A(B &);//转换构造函数,他的作用是用B类对象构造A类对象 void Edita(int temp) { A::a=temp; } public: int a; }; class B { public: B(int a=0) { B::a=a; } int Ra() { return B::a; } operator A()//转换运算符重载函数,他的作用则是将B类对象转换成A类对象 { return *this; } protected: int a; }; A::A(B &temp) { cout<<this<<"|"<<&temp<<endl; A::a=temp.Ra(); } void tp(A temp) { } int main() { B bt(100); A at=A(bt); //tp(bt);//错误,多义性问题,系统不知道如何选择,是选择A(B &)转化构造好呢?还是选择B::operator A()进行转换好呢? tp(A::A(bt));//显示的处理可以消除多义性问题 system("pause"); }
代码中的A at=A(bt);运行正常,因为系统发现对象at还未构造,所以优先选取了A类的转换构造函数处理了,没有产生二义性问题。
但是代码中的tp(bt);编译错误,这是因为函数tp的参数要求的是一个A类对象,而我们给他的则是一个B类对象,而在A类与B类中都有一个类似的操作,可以将B类对象转换成A类对象,系统不知道是选取A类的转换构造函数进行构造处理,还是选择B类中的转换运算符号重载函数处理,系统拒绝从他们两个中选一个,所以编译错误。
我们修改tp(bt)为tp(A::A(bt));编译正常,因为我们显式的明确的告诉系统应该使用A类的转换构造函数处理,所以,显式的告诉计算机应该如何处理数据,通常可以解决多义性问题。 |