哪些c++操作符没有友元函数就不能重载

Which C++ operators can not be overloaded without friend function?

本文关键字:函数 就不能 重载 友元 c++ 操作符 哪些      更新时间:2023-10-16

哪些c++操作符没有友元函数就不能重载?

只需要在以下情况下声明友元:

  1. 将操作符定义为类外的独立函数,并且
  2. 实现需要使用私有函数或变量

否则,你可以实现任何没有友元声明的操作符。为了更具体一点…可以在类内外定义各种操作符*:

 // Implementing operator+ inside a class:
 class T {
   public:
    // ...
    T operator+(const T& other) const { return add(other); }
    // ...
 };
 // Implementing operator+ outside a class:
 class T {
   // ...
 };
 T operator+(const T& a, const T& b) { return a.add(b); }

如果,在上面的例子中,"add"函数是私有的,那么在后一个例子中需要一个友元声明,以便operator+使用它。但是,如果"add"是公共的,那么在该示例中就不需要使用"friend"。只在需要授予访问权限时使用。

*在某些情况下,不能在类中定义操作符(例如,如果您无法控制该类的代码,但仍然希望提供一个定义,无论如何该类型位于左侧)。在这些情况下,关于友元声明的相同语句仍然成立:友元声明仅用于访问目的。只要操作符函数的实现仅依赖于公共函数和变量,就不需要友元声明。

左侧操作数不是类本身的操作符。例如,cout << somtething可以通过定义std::ostream& operator<<(std::ostream& lhs, Something const & rhs);函数,并在类中标记为friend来实现。

编辑:朋友是不需要的,永远不需要。但它可以使事情变得更简单。

使用友元函数的唯一原因是访问私有(包括受保护的)成员变量和函数。

你永远不需要好友函数。如果你不想让运算符是成员(通常是不能修改的二进制操作符)它们的操作数),不要求它必须是友元。在那里然而,有两个理由可以使它成为朋友:

  1. 用于访问私有数据成员,而
  2. 以便在类体中定义它(即使它不是成员),以便ADL将找到它

第二个原因主要适用于模板,但它通常用于定义模板基类中的+-操作符,根据+=-=,所以这是最常见的情况

操作符重载和友好是正交的概念。只要需要访问该类型的私有成员,就需要声明函数(任何函数)friend,因此,如果将操作符重载为非成员的函数,并且该实现需要访问该私有成员,则该操作符应该是友元。

请注意,一般来说最好不要声明friend s,因为这是语言中最高的耦合关系,因此只要可能,您应该根据类型的公共接口实现操作符的自由函数重载(允许您更改类型的实现而不必重写操作符)。在某些情况下,建议将operatorX实现为一个自由函数,而将operatorX=实现为一个公共成员函数(这里有更多关于操作符重载的信息)

在类模板中有一种特殊的极端情况,您可能希望将自由函数操作符声明为模板的友元,以便能够在模板类中定义它,即使它不需要访问私有成员:

template <typename T>
class X {
   int m_data;
public:
   int get_value() const { return m_data; }
   friend std::ostream& operator<<( std::ostream& o, X const & x ) {
      return o << x.get_value();
   }
};

这样做的好处是,您可以以一种简单直接的方式将单个非模板化函数定义为友元。要将定义移到类模板之外,您必须使其成为模板,并且语法变得更加麻烦。

this不在左侧时,或者当this需要隐式转换时,您需要使用友元函数。

编辑:当然,如果你确实需要friend部分以及自由函数部分,

操作符[] -> =

必须是成员函数。

其他可用于重载的二进制操作符可以写成函数形式或成员函数形式。可用于重载的操作符是除

以外的所有一元和二进制c++操作符。

:。:: sizeof typeid ?