0

嗨我有这样的代码,我认为朋友重载运算符和转换运算符都有类似的功能。但是,为什么在这种情况下会调用友元重载运算符呢?有什么规则?

非常感谢!

class A{

    double i;
public:
    A(int i):i(i) {}
    operator double () const { cout<<"conversion operator"<<endl;return i;}                            // a conversion operator
    friend bool operator>(int i, A  a);                            // a friend funcion of operator >
};

bool operator>(int i, A  a ){
    cout<<"Friend"<<endl;
    return i>a.i;
}
int main()
{
    A  aa(1);
     if (0 > aa){
         return 1;
      }
}
4

4 回答 4

4

operator>调用重载不需要转换。为了operator>调用内置函数,必须进行一次转换(用户定义的转换运算符。重载决议更喜欢所需转换次数较少的选项,因此使用重载operator>

请注意,如果您要将重载的定义更改为operator>,例如:

friend bool operator>(double i, A  a);

你会得到一个编译错误,因为重载operator>和内置operator>都需要一次转换,编译器将无法解决歧义。

于 2010-03-13T18:16:48.953 回答
1

我并不是说我的答案得到了标准的支持,但让我们从逻辑上考虑一下。

当您点击此行时:

0 > aa

你有两个选择。您可以致电提供的运营商:

friend bool operator>(int i, A  a);

这是 100% 兼容的,或者您可以进行两次转换以到达目的地!你会选哪一个?

于 2010-03-13T18:14:30.283 回答
0

如果添加转换运算符,则 A 类型的对象可能会在您最不期望的时候转换为 double。

一个好的程序不会为他的类提供意外使用的方法,并且转换运算符为该类打开了在许多意外情况下使用的操作(通常情况下,您会期望编译时错误不是因为的自动类型转换)。

因此,应谨慎对待转换运算符(和单参数构造函数),因为编译器可能会在您最不期望的情况下进行转换。

于 2010-03-13T18:29:56.867 回答
0

之所以调用它,是因为它在表达式的上下文中是完全匹配0 > aa的。事实上,很难弄清楚你是如何提出“为什么”的问题的。从逻辑上讲,如果在这种情况下没有打电话给朋友,人们会期待一个“为什么”的问题。

如果将表达式更改为0.0 > aa,则调用将变得模棱两可,因为中性路径会比其他路径更好。

于 2010-03-13T18:43:02.613 回答