没有朋友功能,哪些C ++运算符不能重载?

时间:2011-10-24 09:55:02

标签: c++ operator-overloading friend-function

没有朋友功能,哪些C ++运算符根本不能重载?

7 个答案:

答案 0 :(得分:4)

如果符合以下条件,您只需要朋友声明:

  1. 您将运算符定义为类外的独立函数,并
  2. 实现需要使用私有函数或变量。
  3. 否则,您可以在没有朋友声明的情况下实现任何运算符。为了使这更具体......可以在类*:

    的内部和外部定义各种运算符
     // 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+使用它。但是,如果“添加”是公开的,则在该示例中不需要使用“朋友”。只有在需要授予访问权限时才会使用好友。

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:1)

你从不需要朋友的功能。如果您不希望操作员 是一个成员(通常是不修改的二元运算符的情况 他们的操作数),没有要求它成为朋友。那里 然而,有两个原因可能使它成为朋友:

  1. 以访问私人数据成员,
  2. 以便在类体中定义它(即使它不是 成员),以便ADL找到它
  3. 第二个原因主要适用于模板,但定义很常见 模拟基类中的+-等运算符,+=-=,所以这是最常见的情况。

答案 4 :(得分:1)

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

请注意,一般情况下最好不要声明friend,因为这是语言中最高的耦合关系,所以只要有可能,你应该在公共接口方面实现运算符的自由函数重载。你的类型(允许你改变类型的实现,而不必重写操作符)。在某些情况下,建议将operatorX实现为operatorX=作为公共成员函数实现的自由函数(更多关于运算符重载here

有一个特定的角落案例,带有类模板,您可能希望将自由函数运算符声明为模板的朋友,只是为了能够在模板类中定义它,即使它不需要访问私人成员:

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

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

运营商 [] - &gt; =

必须是会员职能。

重载可接受的其他二元运算符可以以函数形式或以函数形式写入。 可接受的重载操作符是除

之外的所有一元和二进制C ++运算符

:. :: sizeof typeid?