如何使用用户定义的数据类型对定义的数据类型进行操作?

时间:2013-10-22 10:51:54

标签: c++

这里我试图重载关系运算符。当我将重载函数appyling为类的两个对象然后它正在工作但是当我将它应用于一个对象并浮动值时它会给我一个错误,指出“从'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 个答案:

答案 0 :(得分:1)

您的operator>Distance作为右手操作数,因此如果您将double传递给Distance(const float); Distance(const int = 0, const int = 0); ,则需要进行转换。

问题是你有两个构造词

5.6

并且double的类型为double -> float。两个构造函数都是候选者(因为它们可以用1个参数调用),并且所需的转换(double -> int和{{1}})都不比另一个好。因此,错误说调用是不明确的。

答案 1 :(得分:0)

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

左侧已经是DistanceD

右侧是double5.6

您的编译器尝试将double转换为Distance,但没有合适的构造函数。有一个构造函数需要一个const float,一个构造函数需要零,一个或两个const int s;编译器不能在两者之间做出选择,因此就是错误。

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

  1. 传递float5.6f
  2. 明确将float投射到doublestatic_cast<float>(5.6)
  3. 提供一个采用double
  4. 的构造函数
  5. 提供operator >,其中包含double
  6. 提供采用模板化类型的构造函数。
  7. 提供采用模板类型的operator >

答案 2 :(得分:0)

您的构造函数允许来自float(通过第一个)或int(通过第二个,带有默认的第二个参数)的转换。您正在尝试转换5.6,即double,其中任何一个构造函数都是同等匹配的;因此错误。

一种选择是仅使用floatint进行初始化;将5.6更改为5.6f

另一种选择是从第二个构造函数中删除默认参数,因此它不能用于转换。如果您需要默认构造函数,请添加一个,或者为转换构造函数添加默认参数。

其他选项是添加更多重载以转换或与double进行比较。但这开始变得相当混乱。

答案 3 :(得分:0)

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

bool operator >(const double);

但它确定它可以通过您提供的构造函数隐式地将D转换为Distance,然后使用您的bool operator >(const Distance)。但是,有两种方法可以double -> int -> Distancedouble -> float -> Distance。虽然,它无法分辨哪种方式更合适,因此也就是错误。

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

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

另请注意两件事:

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

  2. 看看如果你没有提供float转换构造函数会发生什么。编译器不会消除歧义。但这不会很好。它会将double条带化为int,然后转换为Distance,会失去很多精确度。在声明此类构造函数时,使用explicit关键字是明智的。因此我建议将其声明为explicit Distance(const int = 0, const int = 0);,以避免意外错误。他们可能很讨厌追查。如果允许的话,编译器可以很容易地创建奇怪的转换链,这并不总是可取的。