定义一个带有两个类引用的全局运算符和定义一个只接受正确操作数的成员运算符之间有区别吗?
全局:
class X
{
public:
int value;
};
bool operator==(X& left, X& right)
{
return left.value == right.value;
};成员:
class X
{
int value;
bool operator==( X& right)
{
return value == right.value;
};
}发布于 2009-07-17 18:54:28
使用非成员运算符(通常声明为friends)的一个原因是因为左侧是执行操作的那个。Obj::operator+适用于:
obj + 2而是为了:
2 + obj恐怕行不通。为此,您需要类似以下内容:
class Obj
{
friend Obj operator+(const Obj& lhs, int i);
friend Obj operator+(int i, const Obj& rhs);
};
Obj operator+(const Obj& lhs, int i) { ... }
Obj operator+(int i, const Obj& rhs) { ... }发布于 2009-07-17 20:53:25
您最聪明的选择是将其设置为好友函数。
正如JaredPar提到的,全局实现不能访问受保护的和私有的类成员,但是成员函数也有一个问题。
C++将允许函数参数的隐式转换,但不允许this.的隐式转换
如果存在可以转换为X类的类型:
class Y
{
public:
operator X(); // Y objects may be converted to X
};
X x1, x2;
Y y1, y2;只有下面的一些表达式可以使用成员函数进行编译。
x1 == x2; // Compiles with both implementations
x1 == y1; // Compiles with both implementations
y1 == x1; // ERROR! Member function can't convert this to type X
y1 == y2; // ERROR! Member function can't convert this to type X两全其美的解决方案是以朋友的身份实现这一点:
class X
{
int value;
public:
friend bool operator==( X& left, X& right )
{
return left.value == right.value;
};
};发布于 2009-07-17 21:01:16
总结一下Codebender的答案:
成员运算符是不对称的。编译器不能使用左侧运算符和右侧运算符执行相同数量的操作。
struct Example
{
Example( int value = 0 ) : value( value ) {}
int value;
Example operator+( Example const & rhs ); // option 1
};
Example operator+( Example const & lhs, Example const & rhs ); // option 2
int main()
{
Example a( 10 );
Example b = 10 + a;
}在上面的代码中,如果运算符是成员函数,将无法编译,而如果运算符是自由函数,则将按预期工作。
通常,一种常见的模式是实现运算符,这些运算符必须是成员函数,其余的作为委托给成员运算符的自由函数:
class X
{
public:
X& operator+=( X const & rhs );
};
X operator+( X lhs, X const & rhs )
{
lhs += rhs; // lhs was passed by value so it is a copy
return lhs;
}https://stackoverflow.com/questions/1145022
复制相似问题