-1

在这里,我试图重载关系运算符。当我将重载函数应用到类的两个对象时,它正在工作,但是当我将它应用到一个对象和浮点值时,它给了我一个错误,指出“从'double'到'distance'的转换是模棱两可的”。请帮忙。

#include <iostream>

using namespace std;

class Distance
{
    int iFeet;
    float fInches;
public:
    Distance(const float);
    Distance(const int = 0, const int = 0);
    bool operator >(const Distance);
};

Distance::Distance(const float p)
{
    iFeet = int(p);
    fInches = (p - iFeet) * 12;
}

Distance::Distance(const int a, const int b)
{
    iFeet = a;
    fInches = b;
}

bool Distance::operator>(const Distance dd1)
{
    if (iFeet > dd1.iFeet)
        return true;
    if (iFeet == dd1.iFeet && fInches > dd1.fInches)
        return true;

    return false;
}

int main()
{
    Distance D(1, 6), D2(1, 8);
    if (D > D2)
        cout << "D is gtreater than D2" << endl;
    else
        cout << "D2 is greater than D" << endl;

    if (D > 5.6)
        cout << "D is greateer" << endl;
    else
        cout << "D is not greater" << endl;
    return 0;
}
4

4 回答 4

1

operator>将 aDistance作为右手操作数,因此如果您将其传递 a double,则需要进行转换。

问题是你有两个构造函数

Distance(const float);
Distance(const int = 0, const int = 0);

并且类型5.6double。两个构造函数都是候选者(因为可以使用 1 个参数调用它们),并且所需的转换 (double -> floatdouble -> int) 都不比另一个更好。因此,错误说呼叫是模棱两可的。

于 2013-10-22T11:01:18.853 回答
0

编译器很困惑,因为它无法执行您明确要求它执行的操作,即没有

bool operator >(const double);

但它发现它可以通过您提供的构造函数隐式转换DDistance,然后使用您的bool operator >(const Distance). 但是,有两种方法可以做到这一点double -> int -> Distancedouble -> float -> Distance. 虽然,它无法判断哪种方式更合适,因此会出现错误。

您可以为 double: 提供重载运算符,也可以bool operator >(const double); 为 double 类型提供显式构造函数Distance(double)

我建议编写一个适当的比较运算符,因为使用构造函数会有一个隐式转换和一个临时Distance对象创建(尽管在简单的情况下它可能会被编译器优化)。

另外请注意两点:

  1. 您应该将运算符操作数声明为引用(无论如何它都是 const),即bool operator >(const Distance&);. 它避免了创建对象的隐式副本。copy-by-value在当前状态下,由于参数传递,编译器需要为临时 rhs 操作数对象调用复制构造函数。

  2. 看看如果你不提供float转换构造函数会发生什么。编译器不会有歧义。但这不会很好。它会分解doubleint,然后转换为Distance,从而失去很多精度。在声明此类构造函数时使用explicit关键字是明智的。所以我建议将其声明为explicit Distance(const int = 0, const int = 0);只是为了避免意外错误。他们可能很难追踪。如果允许,编译器很容易创建奇怪的转换链,这并不总是可取的。

于 2013-10-22T11:13:30.480 回答
0

您的重载operator >仅适用于两个Distance对象之间的比较。

左边已经是Distance, D

右手边是double,5.6

您的编译器尝试将 转换double为 aDistance但没有合适的构造函数。有一个构造函数接受 aconst float和一个接受零、一个或两个const ints 的构造函数;编译器无法在两者之间进行选择,因此出现错误。

您可以通过多种方式解决此问题:

  1. 通过一个float5.6f
  2. 明确地将您float转换为doublestatic_cast<float>(5.6)
  3. 提供一个接受double.
  4. 提供一个operator >需要一个double.
  5. 提供一个采用模板类型的构造函数。
  6. 提供一个operator >采用模板类型的。
于 2013-10-22T11:00:52.777 回答
0

您的构造函数允许从float(通过第一个)或int(通过第二个,使用默认的第二个参数)进行转换。您正在尝试转换5.6, 这是 a double,其中任一构造函数都是同样好的匹配;因此错误。

一种选择是仅使用floatint初始化它;更改5.65.6f.

另一种选择是从第二个构造函数中删除默认参数,因此它不能用于转换。如果你想要一个默认构造函数,要么添加一个,要么给转换构造函数添加一个默认参数。

其他选项是添加更多重载以从double. 不过,这开始变得相当混乱。

于 2013-10-22T11:03:47.933 回答