我非常混淆将操作符重载的想法作为成员和非成员函数。
当我们将运算符作为非成员函数重载时,我们实际上是什么意思,类似地,当我们将运算符作为成员函数重载时,我们的意思是什么。虽然我知道非成员函数是朋友函数。
答案 0 :(得分:1)
如果将操作符作为非成员函数重载,则需要在参数列表中指定要特定操作的对象。
如果将其作为成员函数重载,“this”指针将为您完成部分工作。
考虑以下示例:
class Test {
public:
friend Test operator+(const Test &lhs, const Test &rhs); // Non-member function
Test operator+(const Test &rhs); // Member function
};
两者之间的区别在于非成员函数没有编译器在您讨论类的特定实例时方便地为您传递的this
指针。
成员函数1推断了lhs,因此您只需要提供rhs。
请注意,“朋友”不是必需的,但如果您想访问Test的私人会员,则需要它。
编译器可以根据参数计数消除歧义。如果你想声明friend Test operator+(const Test &rhs)
,它会抱怨参数不足,因为+是一个二元运算符。成员函数operator +的lhs是“this
”。
答案 1 :(得分:0)
例如
class Foo {
public:
Foo operator+(Foo) // member variant
// declared inside the function
}; // end of class
Foo operator+(Foo lhs, Foo rhs) // non-member variant
{ // declared outside the class
// could be just a call to the member variant
lhs.operator+(rhs);
// I usually do this when implementing std::stream operators,
// don't remember why just now.
}
非会员不需要被告知,但可能需要访问内部状态。 如果我没记错的话,非成员在某些编译器上的模板化代码和命名空间方面有一些优势,非成员变体中的朋友也可以很好地记录在类之外有一个特定的函数到这堂课。它告诉我,如果我改变那个类,我可能不得不查看非成员操作员,以确保我没有破坏任何东西。
答案 2 :(得分:0)
大多数运营商应被定义为成员。
class MyClass
{
...
public:
const MyClass& operator+=(const MyClass&);
};
这与以下行为相同:
class MyClass {...};
const MyClass& operator+=(const MyClass&, const MyClass&);
第一个示例中隐含的this
与第二个示例的第一个参数类似。如果第二个示例需要访问内部状态MyClass
,则需要friend
编辑。
class MyClass
{
friend const MyClass& operator+=(const MyClass&, const MyClass&);
};
const MyClass& operator+=(const MyClass&, const MyClass&);
operator<<
std::ostream
上的原型例外情况为std::ostream& operator<<(std::ostream&, const MyClass&);
。
MyClass
这在逻辑上是std::ostream
的成员,但由于参数的排序,它必须是两个类的非成员或std::ostream
的成员。由于您无法将成员添加到{{1}},因此必须将其定义为非成员。
答案 3 :(得分:0)
一个小例子:(我还没有尝试编译这段代码,但我希望它有效)
class MyClass
{
public:
MyClass operator+(const MyClass& other) const; //member operator declaration
friend MyClass operator-(const MyClass& first, const MyClass& second); //non-member operator friend declaration
private:
int _a;
}
//member operator definition
MyClass MyClass::operator+(const MyClass& other) const
{
MyClass result;
result._a = _a + other._a;
return result;
}
//non-member operator definition
MyClass MyClass::operator-(const MyClass& first, const MyClass& second)
{
MyClass result;
result._a = first._a - second._a;
return result;
}
注意差异:在成员运算符定义中,我没有在“=”之后的第一个_a之前指定任何内容 - 假设这是-a; _a。
只有当类的实例是运算符的第一个参数时,才能使用成员运算符函数。例如,如果您想要执行2 + myClassObject
之类的操作,则需要覆盖非成员运算符MyClass MyClass::operator+(int first, const MyClass& second)
(或者您希望具有的任何返回值)。
另请注意,我只需要非会员运营商的友情声明才能访问私人_a
字段。