C++ - 必须在头文件中定义友元函数吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8373410/
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
C++ - must friend functions be defined in the header file?
提问by Pacane
I want to overload the operator << in one of my classes. The signature goes like this:
我想在我的一个类中重载运算符 << 。签名是这样的:
friend std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
When I try to define it in the .cpp file it says that the operator<< exactly takes 1 argument, however, when I define it in the .h, it compiled/works fine.
当我尝试在 .cpp 文件中定义它时,它说 operator<< 正好需要 1 个参数,但是,当我在 .h 中定义它时,它编译/工作正常。
This is how I define it in the .cpp file :
这是我在 .cpp 文件中定义它的方式:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ... }
Does it have anything to do with friend functions needing to be defined in header files?
它与需要在头文件中定义的朋友函数有什么关系吗?
回答by Xeo
It can be definedin a cpp file, but it needs to at least be declaredin a header file, otherwise all places where you want to use it will only see the stuff the stream itself gives you, not your overload.
它可以在 cpp 文件中定义,但至少需要在头文件中声明,否则所有你想使用它的地方只会看到流本身给你的东西,而不是你的重载。
// .h and in class
friend std::ostream& operator<<(std::ostream& os, MyClass const& v);
// .cpp
std::ostream& operator<<(std::ostream& os, MyClass const& v){
// print it
}
回答by ruakh
The problem is with the way you're defining it. It's not a memberof the class, it's just a friendof the class. You need to drop the Annuaire::
prefix. So, change this:
问题在于你定义它的方式。它不是班级的成员,只是班级的朋友。您需要删除Annuaire::
前缀。所以,改变这个:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ...
to this:
对此:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj){ // ...
The reason for the error message is that Annuaire::operator<<(std::ostream& os, const Annuaire& obj)
would expect three arguments: the Annuaire
instance that it's called on (as this
), and and two additional arguments (os
and obj
).
错误消息的原因是Annuaire::operator<<(std::ostream& os, const Annuaire& obj)
需要三个参数:Annuaire
调用它的实例 (as this
) 和两个附加参数 ( os
and obj
)。
回答by Jorge Paulo
As mentioned in David's answer, in this case the operator is not a member function, it is merely a friend function in the same namespace. This pointed me in the right direction in solving a very similar issue.
正如大卫的回答中提到的,在这种情况下,运算符不是成员函数,它只是同一命名空间中的友元函数。这为我指明了解决非常相似问题的正确方向。
I'm posting this answer because it wasn't immediately obvious to me. Maybe because the implementation file where I was adding the operator wasn't fully enclosed in the namespace, and used a using-directive instead.
我发布这个答案是因为它对我来说并不是很明显。可能是因为我添加操作符的实现文件没有完全包含在命名空间中,而是使用了 using 指令。
Shouldn't be relevant but I'm using VS2013.
不应该相关,但我使用的是 VS2013。
//Foo.h
namespace Bar{
class Foo
{
public:
Foo();
private:
int n;
friend std::ostream & operator<<(std::ostream &, Foo const &);
};
}
//Foo.cpp
using namespace Bar; //won't apply to the operator definition
Foo::Foo(){}// doesn't require the Bar qualifier because of the using-directive
//the operator required the Bar namespace qualifier
std::ostream & Bar::operator<<(std::ostream & o, Foo const & x)
{
return o << x.n;
}
回答by David Rodríguez - dribeas
Friend functions, even if they seemto be declared inside the class are not member functions but rather namespace level functions (in the enclosing namespace). In your code you declare the friend function correctly, but you try to define it as a member function of the class:
友元函数,即使它们似乎在类内部声明,也不是成员函数而是命名空间级别的函数(在封闭的命名空间中)。在您的代码中,您正确声明了友元函数,但您尝试将其定义为类的成员函数:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){
That definition would be for a member function of Annuaire
, called operator<<
, that takes two arguments, which is invalid as operator<<
can be overloaded in one of two ways: as a free function taking two arguments (left hand side and right hand side) or as a member function of the class that appears in the lhs of the expression taking an argument of the rhs type. In this particular case, since the lhs is std::ostream
and you cannot modify it, you are left with the only option of using a free function:
该定义适用于Annuaire
, 被调用的成员函数operator<<
,它接受两个参数,这是无效的,因为operator<<
可以通过以下两种方式之一重载:作为接受两个参数(左侧和右侧)的自由函数或作为成员出现在表达式的 lhs 中的类的函数,采用 rhs 类型的参数。在这种特殊情况下,由于 lhs 是std::ostream
并且您无法修改它,因此您只能选择使用自由函数:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
回答by Kerrek SB
No such restriction; you're probably just writing it wrong. Should be something like this:
没有这样的限制;你可能只是写错了。应该是这样的:
class Foo
{
int n;
friend std::ostream & operator<<(std::ostream &, Foo const &);
};
std::ostream & operator<<(std::ostream & o, Foo const & x)
{
return o << x.n;
}