没有朋友功能,哪些C ++运算符根本不能重载?
答案 0 :(得分:4)
如果符合以下条件,您只需要朋友声明:
否则,您可以在没有朋友声明的情况下实现任何运算符。为了使这更具体......可以在类*:
的内部和外部定义各种运算符 // 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)
你从不需要朋友的功能。如果您不希望操作员 是一个成员(通常是不修改的二元运算符的情况 他们的操作数),没有要求它成为朋友。那里 然而,有两个原因可能使它成为朋友:
第二个原因主要适用于模板,但定义很常见
模拟基类中的+
和-
等运算符,+=
和-=
,所以这是最常见的情况。
答案 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?