当两个类定义了转换时的二义性解决方案
当两个类定义了转换时的二义性
我在看《C++primer》时看到以下内容,不大理解,烦请各位高手解答,谢谢,谢谢!!
“函数compute接受一个SmallInt的实参,在这里int_val既可以通过SmallInt类的构造函数也可以通过Integral类定义的转换操作符,把Integral类的对象int_val转换为SmallInt类类型,所以这个调用具有二义性。”
既然是这样的话,就应该可以把调用函数时的两种转换用代码的形式写出来:
那么,(1)应该是int_val对象调用了它的成员函数,调用时,它本质上传递了一个this指针 。而(2)中传递对象int_val就是将int_val复制给 SmallInt构造函数的形参。这两个调用没有一个调用比另一个更好,所以具有二义性。
但是,接下来书中说到的“把SmallInt类的构造函数修改为SmallInt(const Integral&); 可以消除二义性”让我非常不解。而且书中给出的原因是“SmallInt构造函数需要将引用绑定到int_val,而使用Integral类的转换操作符可以避免这个额外操作”。
我的问题是,使用Integral类的转换操作符虽然可以避免这个额外操作,但它本质上免不了将this指针传递给函数(我的猜想),一个调用传递指针,一个需要将引用绑定,这两个调用应该没有高下之分,为什么这点小小的区别却能使我们更倾向与使用转换操作符。假如以上的猜想不成立,那么最开始的函数调用就应该没有二义性!
实在是头都搞大了,希望高手解答,再次感谢!祝你们周末愉快!!
------解决方案--------------------
class Integral{
public:
operator SmallInt() const; //隐式类型转化
// ...
};
void compute(SmallInt);
Integral int_val;
compute(int_val); //int_val调用隐式类型转化,转化为SmallInt。。。
------解决方案--------------------
形参SmallInt类型 传递实参Integral类型
那么SmallInt的这个以Integral为参数的构造函数或者Integral转换成SmallInt的转换操作符函数都可以被调用, 而它们在编译器中并没有谁更优一些 故会编译失败
为什么改为 SmallInt(const Integral&); 就消除二义性了呢
这个我也想知道
刚才去试了一下
貌似是不行的
------解决方案--------------------
我不知道LZ看的是第几版,我这的第三版有关用户定义转换的一张的描述和LZ说不一样
我在看《C++primer》时看到以下内容,不大理解,烦请各位高手解答,谢谢,谢谢!!
- C/C++ code
class Integral; class SmallInt{ public: SmallInt(Integral); // ... }; class Integral{ public: operator SmallInt() const; // ... }; void compute(SmallInt); Integral int_val; compute(int_val);
“函数compute接受一个SmallInt的实参,在这里int_val既可以通过SmallInt类的构造函数也可以通过Integral类定义的转换操作符,把Integral类的对象int_val转换为SmallInt类类型,所以这个调用具有二义性。”
既然是这样的话,就应该可以把调用函数时的两种转换用代码的形式写出来:
- C/C++ code
int_val.operator SmallInt(); //(1) SmallInt(int_val); //(2)
那么,(1)应该是int_val对象调用了它的成员函数,调用时,它本质上传递了一个this指针 。而(2)中传递对象int_val就是将int_val复制给 SmallInt构造函数的形参。这两个调用没有一个调用比另一个更好,所以具有二义性。
但是,接下来书中说到的“把SmallInt类的构造函数修改为SmallInt(const Integral&); 可以消除二义性”让我非常不解。而且书中给出的原因是“SmallInt构造函数需要将引用绑定到int_val,而使用Integral类的转换操作符可以避免这个额外操作”。
我的问题是,使用Integral类的转换操作符虽然可以避免这个额外操作,但它本质上免不了将this指针传递给函数(我的猜想),一个调用传递指针,一个需要将引用绑定,这两个调用应该没有高下之分,为什么这点小小的区别却能使我们更倾向与使用转换操作符。假如以上的猜想不成立,那么最开始的函数调用就应该没有二义性!
实在是头都搞大了,希望高手解答,再次感谢!祝你们周末愉快!!
------解决方案--------------------
class Integral{
public:
operator SmallInt() const; //隐式类型转化
// ...
};
void compute(SmallInt);
Integral int_val;
compute(int_val); //int_val调用隐式类型转化,转化为SmallInt。。。
------解决方案--------------------
形参SmallInt类型 传递实参Integral类型
那么SmallInt的这个以Integral为参数的构造函数或者Integral转换成SmallInt的转换操作符函数都可以被调用, 而它们在编译器中并没有谁更优一些 故会编译失败
为什么改为 SmallInt(const Integral&); 就消除二义性了呢
这个我也想知道
刚才去试了一下
貌似是不行的
------解决方案--------------------
我不知道LZ看的是第几版,我这的第三版有关用户定义转换的一张的描述和LZ说不一样
- C/C++ code
//在为隐式转换选择一个用户定义的转换序列时如果两个类定义了互相转换的函数则 //二义性也可能会出现例如 class SmallInt { public: SmallInt( const Number & ); // ... }; class Number { public: operator SmallInt(); // ... }; extern void compute( SmallInt ); extern Number num; compute( num ); // 错误: 两个可能的转换 //实参num 可以用两种不同的方式被转换成SmallInt 型可以使用构造函数 //SmallInt::SmallInt(const Number&)或转换函数Number::operator SmallInt() 因为这两个函数一 //样好所以这个调用是错的 //程序员可以通过显式地调用Number 类的转换函数解决这种二义性问题 // ok: 显式调用以便解决二义性 compute( num.operator SmallInt() ); //但是程序员不能用显式强制类型转换来解决二义性因为针对这个显式强制转换转 //换函数和构造函数都会被考虑 compute( SmallInt( num ) ); // 错误: 仍然是二义的
------解决方案--------------------
任意开启一个
可以编译
- C/C++ code
class Integral; class SmallInt{ public: //SmallInt(Integral); // ... }; class Integral{ public: operator SmallInt() const; // ... }; // SmallInt::SmallInt(Integral) // { // // } Integral::operator SmallInt() const { return SmallInt(); } void compute(SmallInt) { } int main() { Integral int_val; compute(int_val); return 0; }
------解决方案--------------------
------解决方案--------------------