2012-03-13 86 views
0

我一直在做一些工作,需要有一些它们的运算符重载(=,==,+,!=等)我编写运算符函数,但有时它们是没有被调用,或者编译器的行为就像它不存在一样。 例如:运算符不解析为运算符函数C++

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 
} 

在视觉工作室我去编译,它trows没有操作员需要的东西的左侧参数,然后如果我指定thing2->operator+(&tempThing);那么它的工作原理,这是令人困惑,因为它应该可以解决该如果存在一个Class operator#(Class)函数,并且参数可以转换为合适的类型,那么所有需要的就是使用该运算符,并且编译器将用运算符函数代替它,或者至少调用操作员功能。

thing1 = thing2 + thing3; // written line 
thing1.operator=(thing2.operator+(thing3)); 

为什么我需要指定操作符函数。编译器不应该为我做这件事。

编辑:这是一个关于一般行为的问题,而不是实际的代码正确性。即使我编写语句,因为他们应该由于某种原因必须指定实际的operator(),而不是只能使用该符号。 (我曾与直接的例子,以及复制字符的字符要做到这一点,但有时它的工作)

回答

2

这是常见的款式有operator+operator-,等等,你的类或类和operator+=operator-= ...朋友的功能,作为一个成员函数。这是因为后者正在修改对象本身,而第一个对象正在处理两个对象并返回第三个对象。下面是string类的样本代码可能看起来像:

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; 

也应该工作。

1

要添加功能

Thing tempThing(); 
thing1 = thing2 + &tempThing; 

Thing tempThing();的指针声明返回事物的功能,Thing tempThing;创建事情

也:

operator==, operator+ 

小号应该可能是const

4
Thing tempThing(); 

这不是你可能认为的原因。谷歌的“最令人头疼的解析”。

thing1 = thing2 + &tempThing; 

由于您operator+需要引用(不是指针),你不想把地址。一旦你解决了前面的定义,它应该编译好,如thing1 = thing2 + tempThing;

但是,一般来说,您希望避免使用成员函数来重载大多数操作符。问题在于,这样做可以将右操作数转换为正确的类型,而不是左操作数。通过使用全局超载,您可以获得对称性 - 可以转换操作数。