运算符函数作为成员函数和非成员函数
Operator Functions as Member Functions and Nonmember Functions
我对将运算符重载作为成员和非成员函数的想法感到非常困惑。
当我们将运算符重载为非成员函数时,我们实际上是什么意思,同样,当我们将运算符重载为成员函数时,我们是什么意思。虽然我知道非成员函数是友元函数。
如果将运算符重载为非成员函数,则需要在参数列表中指定要专门操作的对象。
如果将其重载为成员函数,则"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)
,它会抱怨参数不足,因为+是一个二元运算符。成员函数运算符+的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:
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
字段。
大多数运算符应定义为成员。
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
,因此必须将其定义为非成员。
- 如何使用指针传递给函数的数组中对象的函数成员
- c++构造函数成员初始化:传递参数
- 创建 std::函数,它返回具有函数成员值的变量.分段错误
- 如何在C++通过公共函数访问私有函数成员?
- 解释了构造函数成员初始化列表
- 调用std::函数成员时内存损坏
- 是否可以为模板类的模板函数成员设置别名?
- 捕获 lambda 函数C++成员变量
- 构造函数成员初始值设定项跨成员列出,安全吗?
- 获取与在模板参数中传递的函数成员类型相同的类
- 如何从公共函数成员访问地图私有成员
- C 构造函数成员分配优化
- 使用命名空间进行函数成员定义
- 函数成员作为 CUDA 内核的参数
- 模板基类函数成员的别名
- 函数成员中用于void和继承的enable_if
- 头文件中是否定义了一个很长的Class函数成员
- 类内/构造函数成员初始化
- 使用指向部分专用函数成员的指针自动填充向量
- 指向函数成员的指针