C++ 哪些操作符应该声明为友元?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6255825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What operators should be declared as friends?
提问by Rafael S. Calsaverini
In some books and often around the internet I see recommendations like "operator==
should be declared as friend".
在一些书中,经常在互联网上,我看到诸如“operator==
应该被宣布为朋友”之类的建议。
How should I understand when an operator must be declared as friend and when it should be declared as member? What are the operators that will most often need to be declared as friends besides ==
and <<
?
我应该如何理解何时必须将运算符声明为朋友以及何时应将其声明为成员?除了==
and之外,哪些运算符最常需要声明为朋友<<
?
回答by Chris Frederick
This really depends on whether a class is going to be on the left- or right-hand side of the call to operator==
(or other operator). If a class is going to be on the right-hand side of the expression—and does not provide an implicit conversion to a type that can be compared with the left-hand side—you need to implement operator==
as a separate function or as a friend
of the class. If the operator needs to access private class data, it mustbe declared as a friend
.
这实际上取决于类是位于调用operator==
(或其他运算符)的左侧还是右侧。如果一个类将是对的右侧表达,并且不提供的隐式转换为可以用左手进行比较的型面,你需要实现operator==
作为一个单独的函数或作为friend
的班上。如果运算符需要访问私有类数据,则必须将其声明为friend
.
For example,
例如,
class Message {
std::string content;
public:
Message(const std::string& str);
bool operator==(const std::string& rhs) const;
};
allows you to compare a message to a string
允许您将消息与字符串进行比较
Message message("Test");
std::string msg("Test");
if (message == msg) {
// do stuff...
}
but not the other way around
但不是反过来
if (msg == message) { // this won't compile
You need to declare a friend operator==
inside the class
您需要operator==
在类中声明一个朋友
class Message {
std::string content;
public:
Message(const std::string& str);
bool operator==(const std::string& rhs) const;
friend bool operator==(const std::string& lhs, const Message& rhs);
};
ordeclare an implicit conversion operator to the appropriate type
或将隐式转换运算符声明为适当的类型
class Message {
std::string content;
public:
Message(const std::string& str);
bool operator==(const std::string& rhs) const;
operator std::string() const;
};
ordeclare a separate function, which doesn't need to be a friend if it doesn't access private class data
或者声明一个单独的函数,如果它不访问私有类数据就不需要是朋友
bool operator==(const std::string& lhs, const Message& rhs);
回答by Alexander Gessler
When you have your operators outside the class, both parameters can participate in implicit type conversions (whereas with operators being defined in the class body, only the right-hand operands can). Generally, that's a benefit for all the classic binary operators (i.e. ==
,!=
, +
, -
, <<
, ... ).
当您在类之外使用运算符时,两个参数都可以参与隐式类型转换(而在类主体中定义运算符时,只有右侧操作数可以)。通常,这对所有经典的二元运算符(即==
, !=
, +
, -
, <<
, ... )都有好处。
Of course you should only declare operators friend
s of your class if you need to and not if they compute their result solely based on public members of the class.
当然,您应该只在需要时声明friend
您的类的运算符,如果它们仅根据类的公共成员计算结果,则不应声明。
回答by CB Bailey
Generally, only operators which are implemented as free functions that genuinely need to access to private or protected data of the class that they operate on should be declared as friends, otherwise they should just be non-friend non-member functions.
通常,只有作为真正需要访问它们操作的类的私有或受保护数据的自由函数实现的运算符才应该被声明为友元函数,否则它们应该只是非友元非成员函数。
Generally, the only operators that I implement as member functions are those that are fundamentally asymmetric and where the operands don't have equivalent roles. The ones that I tend to implement as members are those required to be members: simple assignment, ()
, []
and ->
together with compound assignment operators, unary operators and perhaps some overloads of <<
and >>
for classes that are themselves stream or stream-like classes. I never overload &&
, ||
or ,
.
通常,我作为成员函数实现的唯一运算符是那些根本不对称且操作数没有等效角色的运算符。我倾向于作为成员实现的那些是那些需要成为成员的:简单赋值、()
,[]
以及->
复合赋值运算符、一元运算符以及可能是一些本身是流或类流类的类的重载<<
和>>
类的重载。我从不超载&&
,||
或者,
。
All other operators I tend to implement as free functions, preferably using the public interface of the classes which they operate on, falling back to being friends only where necessary.
我倾向于将所有其他操作符实现为自由函数,最好使用它们操作的类的公共接口,仅在必要时才返回朋友。
Keeping operators such as !=
, ==
, <
, +
, /
, etc as non-member functions enables identical treatment of the left and right operands with respect to implicit conversion sequences which helps to reduce the number of surprising asymmetries.
保持运营商如!=
,==
,<
,+
,/
,等作为非成员函数使得能够相对于隐式转换序列,其有助于减少令人惊讶的不对称的数量的左和右操作数中的相同的处理。