我很困惑将运算符重载为成员和非成员函数的想法。
当我们将运算符重载为非成员函数时,我们实际上是什么意思,同样,当我们将运算符重载为成员函数时,我们的意思是什么。虽然我知道非成员函数是友元函数。
我很困惑将运算符重载为成员和非成员函数的想法。
当我们将运算符重载为非成员函数时,我们实际上是什么意思,同样,当我们将运算符重载为成员函数时,我们的意思是什么。虽然我知道非成员函数是友元函数。
如果将运算符重载为非成员函数,则需要在参数列表中指定要专门对其进行操作的对象。
如果您将其作为成员函数重载,“this”指针将为您完成部分工作。
考虑以下示例:
class Test {
public:
friend Test operator+(const Test &lhs, const Test &rhs); // Non-member function
Test operator+(const Test &rhs); // Member function
};
this
两者之间的区别在于,当您谈论类的特定实例时, 非成员函数没有编译器方便地为您传递的指针。
成员函数 one 已推断出 lhs,因此您只需提供 rhs。
请注意,“朋友”不是必需的,但如果您想访问 Test 的私人成员,则需要它。
编译器可以根据参数计数来消除歧义。如果你想声明friend Test operator+(const Test &rhs)
,它会抱怨参数不足,因为 + 是一个二元运算符。成员函数 operator+ 的 lhs 是 " this
"。
例子
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.
}
非成员不需要成为朋友,但如果它需要访问内部状态,则可能是。如果我没记错的话,非成员在某些编译器上的模板化代码和命名空间方面具有一些优势到这堂课。它告诉我,如果我更改该类,我可能必须检查非成员运算符以确保我没有破坏任何东西。
大多数运营商应该被定义为成员。
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<<
on std::ostream
。
std::ostream& operator<<(std::ostream&, const MyClass&);
这在逻辑上是您的成员MyClass
,但由于参数的顺序,它必须是两个类的非成员或std::ostream
. 因为您不能向 中添加成员std::ostream
,所以必须将其定义为非成员。
一个小例子:(我没有尝试编译这段代码,但我希望它能工作)
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 之前指定任何内容 - 假定为 this->_a。
只有当您的类的实例是运算符的第一个参数时,才能使用成员运算符函数。例如,如果您想做类似的事情2 + myClassObject
,则需要覆盖非成员运算符MyClass MyClass::operator+(int first, const MyClass& second)
(或使用您希望它具有的任何返回值)。
另请注意,我只需要我的非会员操作员才能访问私有_a
字段的友谊声明。