哪些c++操作符没有友元函数就不能重载
Which C++ operators can not be overloaded without friend function?
哪些c++操作符没有友元函数就不能重载?
只需要在以下情况下声明友元:
- 将操作符定义为类外的独立函数,并且
- 实现需要使用私有函数或变量
否则,你可以实现任何没有友元声明的操作符。为了更具体一点…可以在类内外定义各种操作符*:
// 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
来实现。
使用友元函数的唯一原因是访问私有(包括受保护的)成员变量和函数。
你永远不需要好友函数。如果你不想让运算符是成员(通常是不能修改的二进制操作符)它们的操作数),不要求它必须是友元。在那里然而,有两个理由可以使它成为朋友:
- 用于访问私有数据成员,而
- 以便在类体中定义它(即使它不是成员),以便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 ?
- 为什么函数名不能与返回名类型相同?
- 可变参数函数模板不能很好地使用 std::function 作为参数
- 为什么用户定义的转换函数模板不能有推导的返回类型?
- 为什么静态成员函数定义不能有关键字"static"?
- 使用 std::is_same,为什么我的函数仍然不能用于 2 种类型
- 使用 std::vector<Particle> 粒子;函数 .at() 不能与迭代器一起使用,它作为 for 循环中的参数
- 为什么带有 const 关键字的构造函数可以工作,而没有它就不能工作?
- c++类函数在另一个函数中不能按预期工作
- MSVC constexpr 函数 'xyz' 不能产生常量表达式
- 为什么这个enable_if函数模板不能专门用于VS2017?
- 使用复制构造函数C++不能正常工作
- 为什么没有构造函数就不能创建对象?
- 为什么没有enable_if就不能编译
- 为什么函数"strlen"不能像这样修改"ch1"的长度?
- 为什么我的打印函数会吐垃圾,而我当前的函数却不能正常工作
- 运算符=函数和加法函数似乎不能共存
- 函数指针-不能更改函数签名,我有什么选择
- 如果一个引用一旦被初始化为一个对象,它就不能被改变,为什么这样做呢?
- 哪些c++操作符没有友元函数就不能重载
- 没有对象就不能调用成员函数