哪个 C++没有友元函数就不能重载运算符吗?

发布于 2024-12-11 17:05:50 字数 35 浏览 0 评论 0原文

哪些 C++ 运算符在没有友元函数的情况下根本无法重载?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

臻嫒无言 2024-12-18 17:05:50

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

  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”。仅当需要授予访问权限时才使用好友。

*在某些情况下,无法在类内部定义运算符(例如,如果您无法控制该类的代码,但仍然希望提供该类型位于左侧的定义,无论如何) 。在这些情况下,有关友元声明的相同声明仍然适用:仅出于访问目的才需要友元声明。只要运算符函数的实现仅依赖于公共函数和变量,就不需要友元声明。

You only need a friend declaration if:

  1. You define the operator as a standalone function outside the class, and
  2. The implementation needs to use private functions or variables.

Otherwise, you can implement any operator without a friend declaration. To make this a little bit more concrete... one can define various operators both inside and outside of a class*:

 // 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); }

If, in the example above, the "add" function were private, then there would need to be a friend declaration in the latter example in order for operator+ to use it. However, if "add" is public, then there is no need to use "friend" in that example. Friend is only used when granting access is needed.

*There are cases where an operator cannot be defined inside a class (e.g. if you don't have control over the code of that class, but would still like to provide a definition where that type is on the left-hand side, anyway). In those cases, the same statement regarding friend declarations still holds true: a friend declaration is only needed for access purposes. As long as the implementation of the operator function relies only on public functions and variables, a friend declaration is not needed.

总攻大人 2024-12-18 17:05:50

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

编辑:永远不需要交友。但它可以让事情变得更简单。

The operators where the left-hand-side operand is not the class itself. For example cout << somtething can be achieved via defining a std::ostream& operator<<(std::ostream& lhs, Something const & rhs); function, and marking them as friend inside the class.

EDIT: Friending is not needed, ever. But it can make things simpler.

这样的小城市 2024-12-18 17:05:50

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

The only reason to use friend function is to access the private(including protected) member variable and functions.

胡大本事 2024-12-18 17:05:50

你永远不需要友元函数。如果您不希望运营商
是成员(通常是不修改的二元运算符的情况
他们的操作数),不需要它成为友元。那里
然而,有两个原因可以使其成为友元:

  1. 为了访问私有数据成员,以及
  2. 为了在类主体中定义它(即使它不是一个
    成员),这样ADL就会找到它

第二个原因主要适用于模板,但通常定义
模板基类中的运算符,如 +-,以 += 形式表示
-=,所以这是最常见的情况。

You never need a friend function. If you don't want the operator to
be a member (usually the case for binary operators which do not modify
their operands), there's no requirement for it to be a friend. There
are two reasons one might make it a friend, however:

  1. in order to access private data members, and
  2. in order to define it in the class body (even though it is not a
    member), so that ADL will find it

The second reason mainly applies to templates, but it's common to define
operators like + and - in a template base class, in terms of +=
and -=, so this is the most common case.

屋顶上的小猫咪 2024-12-18 17:05:50

运算符重载和友谊是正交的概念。每当需要访问该类型的私有成员时,您都需要声明一个函数(任何函数)friend,因此,如果您将运算符重载为非成员函数,并且该实现需要访问私人成员,那么它应该是朋友。

请注意,通常最好不要声明 friend,因为这是语言中最高的耦合关系,因此只要有可能,您就应该根据 的公共接口实现运算符的自由函数重载您的类型(允许您更改类型的实现,而无需重写运算符)。在某些情况下,建议将 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();
   }
};

这样做的优点是您可以将单个非模板化函数定义为朋友以简单直接的方式。要将定义移到类模板之外,您必须将其设为模板,并且语法会变得更加麻烦。

Operator overloading and friendship are orthogonal concepts. You need to declare a function (any function) friend whenever it needs access to a private member of the type, so if you overload an operator as a function that is not a member and that implementation needs access to the private members, then it should be friend.

Note that in general it is better not to declare friends, as that is the highest coupling relationship in the language, so whenever possible you should implement even free function overloads of operators in terms of the public interface of your type (allowing you to change the implementation of the type without having to rewrite the operators). In some cases the recommendation would be to implement operatorX as a free function in terms of operatorX= implemented as a public member function (more on operator overloading here)

There is an specific corner case, with class templates, where you might want to declare a free function operator as a friend of the template just to be able to define it inside the template class, even if it does not need access to private members:

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 has the advantage that you define a single non-templated function as a friend in a simple straightforward way. To move the definition outside of the class template, you would have to make it a template and the syntax becomes more cumbersome.

预谋 2024-12-18 17:05:50

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

编辑:当然,如果您确实需要 friend 部分以及免费功能部分。

You need to use a friend function when this is not the left-hand-side, or alternatively, where this needs to be implicitly converted.

Edit: And, of course, if you actually need the friend part as well as the free function part.

过去的过去 2024-12-18 17:05:50

运算符[] -> =

必须是成员函数。

其他可接受重载的二元运算符可以以函数形式或成员函数形式编写。
可接受重载的运算符是除

: 之外的所有一元和二元 C++ 运算符。 :: 类型 ID 的大小?

operators [] -> =

Must be a member functions.

Other binary operators acceptable for overloading can be write in function form or in memeber-function form.
Operators acceptable for overloading is all unary and binary C++ operators except

: . :: sizeof typeid ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文