我一直在做一些需要让它们的某些运算符重载的类(=,==,+,!=等)我编写运算符函数,但有时它们没有被调用,或者编译器表现得好像甚至不存在。 例如:
class Thing{
public:
Thing& operator=(const Thing& _other){
// implementation
}
bool operator==(const Thing& _other){
// implementation
}
Thing& operator+(const Thing& _other){
// implementation
}
};
这包括类的其他成员函数(构造函数(默认),构造函数(复制),析构函数等),但有时会忽略该方法。
void Foo(Thing & thing1, Thing & thing2){
//snip
if(thing1 == thing2){
//do some stuff
}
//snip
Thing tempThing();
thing1 = thing2 + &tempThing;
//snip
}
在Visual Studio中我去编译,它告诉我没有运算符接受Thing的左侧参数,然后如果我指定thing2->operator+(&tempThing);
然后它起作用这是令人困惑的,因为它应解决为运算符函数只是凭借语言解析
如果存在Class operator#(Class)
函数,并且参数可以转换为适当的类型,那么所需要的只是使用运算符,编译器将用运算符函数替换它,或者至少调用操作员函数。
thing1 = thing2 + thing3; // written line
thing1.operator=(thing2.operator+(thing3));
为什么我必须指定运算符函数。不应该让编译器为我做这件事。
编辑:这是关于一般行为的问题,而不是代码的实际正确性。即使我写语句因为它们应该由于某种原因必须指定实际的operator()而不是只能使用符号。 (我必须使用直接示例以及角色的复制角色来执行此操作,但有时它确实有效)
答案 0 :(得分:4)
Thing tempThing();
这不是你可能认为的那样。谷歌的“最令人烦恼的解析”。
thing1 = thing2 + &tempThing;
由于您的operator+
接受引用(而不是指针),因此您不想获取地址。修复前面的定义后,它应该编译为thing1 = thing2 + tempThing;
。
但是,一般来说,您希望避免使用成员函数来使大多数运算符超载。问题是,这样做允许将右操作数转换为正确的类型,而不是左操作数的转换。通过使用全局重载,您可以获得对称性 - 可以转换操作数。
答案 1 :(得分:2)
让operator+
,operator-
等等在您的课程之外或作为您班级的朋友功能operator+=
,operator-=
,这是常见的风格, ......,作为会员的职能。这是因为后者正在修改对象本身,而第一个正在处理两个对象并返回第三个对象。以下是字符串类的示例代码,如下所示:
class string {
public:
string& operator+=(const string& other)
{
this->append(other);
return *this;
}
private:
void append(const string& other)
{
// concatenate two strings here
}
};
string operator+(const string& first, const string& second)
{
string result(first);
result += second;
return result;
}
根据您的情况更改行
Thing tempThing();
thing1 = thing2 + &tempThing;
到
Thing tempThing;
thing1 = thing2 + tempThing;
也应该有用。
答案 2 :(得分:1)
您正在添加功能
的指针Thing tempThing();
thing1 = thing2 + &tempThing;
Thing tempThing();
声明一个返回Thing的函数,Thing tempThing;
创建Thing
也:
operator==, operator+
应该是const