C++ 如何使用用户定义的数据类型对定义的数据类型进行操作?
这里我试图重载关系运算符。当我将重载函数应用于类的两个对象时,它正在工作,但当我将它应用于一个对象和浮点值时,它会给我一个错误,指出“从‘double’到‘distance’的转换是不确定的”。 请帮忙C++ 如何使用用户定义的数据类型对定义的数据类型进行操作?,c++,C++,这里我试图重载关系运算符。当我将重载函数应用于类的两个对象时,它正在工作,但当我将它应用于一个对象和浮点值时,它会给我一个错误,指出“从‘double’到‘distance’的转换是不确定的”。 请帮忙 #include <iostream> using namespace std; class Distance { int iFeet; float fInches; public: Distance(const float); 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;
}
#包括
使用名称空间std;
班距
{
int iFeet;
浮雀;
公众:
距离(常数浮动);
距离(常数int=0,常数int=0);
布尔运算符>(常数距离);
};
距离::距离(常数浮点p)
{
iFeet=int(p);
雀类=(p-iFeet)*12;
}
距离:距离(常数a,常数b)
{
iFeet=a;
雀类=b;
}
布尔距离::运算符>(常数距离dd1)
{
如果(iFeet>dd1.iFeet)
返回true;
if(iFeet==dd1.iFeet&&fInches>dd1.fInches)
返回true;
返回false;
}
int main()
{
距离D(1,6),D2(1,8);
如果(D>D2)
cout重载的操作符>
仅用于比较两个距离
对象
左手边已经是距离
,D
右侧是一个double
,5.6
您的编译器尝试将双精度
转换为距离
,但没有合适的构造函数。有一个构造函数采用常量浮点
,另一个构造函数采用零、一或两个常量int
s;编译器无法在两者之间进行选择,因此出现错误
您可以通过多种方式解决此问题:
传递一个float
,5.6f
显式将您的float
转换为double
:static\u cast(5.6)
提供一个构造函数,该构造函数接受一个double
提供一个运算符>
,该运算符接受一个双精度的
提供采用模板类型的构造函数
提供采用模板类型的运算符>
您的运算符>
将距离
作为右操作数,因此如果您将双精度
传递给它,则需要进行转换
问题是你有两个构造函数
Distance(const float);
Distance(const int = 0, const int = 0);
5.6
的类型是double
。两个构造函数都是候选构造函数(因为它们可以用一个参数调用),并且都不是必需的转换(double->float
和double->int
)比另一个更好。因此,表示调用不明确的错误。您的构造函数允许从float
(通过第一个参数)或int
(通过第二个参数,使用默认的第二个参数)进行转换。您正在尝试转换5.6
,这是一个双精度
,其中任何一个构造函数都是同样好的匹配项;因此出现错误
一个选项是只使用float
或int
对其进行初始化;将5.6
更改为5.6f
另一个选项是从第二个构造函数中删除默认参数,因此无法将其用于转换。如果需要默认构造函数,请添加一个,或向转换构造函数添加默认参数
其他选项是添加更多的重载以从double
进行转换或与之进行比较。但这开始变得相当混乱。编译器感到困惑,因为它无法执行您明确要求它执行的操作,即没有
bool操作符>(常数双);
但它发现它可以通过您提供的构造函数隐式地将D
转换为Distance
,然后使用bool操作符>(const-Distance)
。但是,有两种方法可以执行此操作double->int->Distance
或double->float->Distance
。尽管它无法判断哪种方法更合适,因此会出现错误
您可以为double提供重载操作符:bool操作符>(constdouble);
或双精度类型的显式构造函数距离(双精度)
我建议编写一个适当的比较运算符,因为使用构造函数时,会有一个隐式转换和一个临时的距离对象(尽管在简单的情况下,编译器可能会对其进行优化)
另外,请注意两件事:
您应该将运算符操作数声明为引用(无论如何它都是常量),即bool运算符>(常量距离&);
。它避免创建对象的隐式副本。在当前状态下,编译器将需要调用副本构造函数来创建临时rhs操作数对象,因为按值复制
参数传递
看看如果不提供float
转换构造函数会发生什么情况。编译器不会消除歧义。但这并不好。它会将double
分条到int
,然后转换到Distance
,损失很多精度。在反求时使用explicit
关键字是明智的澄清此类构造函数。因此我建议将其声明为显式距离(const int=0,const int=0);
以避免意外错误。它们可能难以追踪。如果允许的话,编译器可以轻松创建奇怪的转换链,这并不总是可取的