c++必须在头文件中定义友元函数
C++ - must friend functions be defined in the header file?
我想重载操作符<<在我的一节课上。签名是这样的:
friend std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
当我试图在。cpp文件中定义它时,它说操作符<<确切地接受一个参数,但是,当我在。h中定义它时,它编译/工作正常。
我在。cpp文件中是这样定义的:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ... }
它与需要在头文件中定义的友元函数有关吗?
可以在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
}
问题在于你定义它的方式。它不是类的成员,它只是类的好友。需要去掉Annuaire::
前缀。所以,修改这个:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ...
:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj){ // ...
错误消息的原因是Annuaire::operator<<(std::ostream& os, const Annuaire& obj)
期望有三个参数:它被调用的Annuaire
实例(作为this
),以及两个额外的参数(os
和obj
)。
正如David的回答中提到的,在这种情况下,操作符不是成员函数,它仅仅是同一名称空间中的友元函数。这给我指明了解决类似问题的正确方向。
我把这个答案贴出来是因为它对我来说不是很明显。也许是因为我添加运算符的实现文件没有完全包含在命名空间中,而是使用了using指令。
不应该是相关的,但我使用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;
}
友元函数,即使它们看起来是在类内部声明的,也不是成员函数,而是命名空间级函数(在封闭的命名空间中)。在代码中,正确地声明了友元函数,但尝试将其定义为类的成员函数:
std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){
该定义适用于具有两个实参的Annuaire
成员函数operator<<
,由于operator<<
可以通过以下两种方式重载:作为具有两个实参(左侧和右侧)的自由函数,或者作为具有rhs类型实参的类的成员函数出现在表达式的lhs中。在这个特殊的例子中,由于lhs是std::ostream
,您不能修改它,因此您只能选择使用一个自由函数:
std::ostream& operator<<(std::ostream& os, const Annuaire& obj)
无此限制;你可能只是写错了。应该是这样的:
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;
}
- 在模板类之外定义友元函数的正确方法是什么?
- 2个模板化类的非模板友元函数未定义引用错误
- 未定义的类模板不会实例化以检查友元函数
- 在类内定义的友元函数与类外定义的友元函数的查找规则之间的差异
- 具有定义模板还是非模板的友元函数
- 为什么T是未定义的?我正在尝试实现一个用于双链表的节点类,它不喜欢我使用友元运算符后的T
- 模板和隐式构造函数的类定义之外的友元声明
- 为什么我不能定义一元运算符,然后在 MSVC 的模板类中声明具有相同名称的友元二进制运算符?
- 为什么在定义类之前声明类的对象会在友元类中给出错误,而在友元函数中不会出错
- 正确的友元定义,以授予 std::map 对私有默认构造函数的访问权限
- 如何获取指向模板类中定义的友元函数的函数指针
- 在 c++ 中定义命名空间中模板类的友元函数时出现问题
- 当类和函数具有单独的模板参数时,在类定义之外定义友元函数
- 获取内联定义的友元函数的地址
- 我可以有一个从外部不可见但未在标头中定义的静态友元函数吗?
- 如何正确定义无友元函数
- 如何在局部类中定义友元函数运算符>>?
- 在类中定义友元用户定义的文字运算符
- 在类内定义友元函数模板的情况下,如何避免重定义错误
- c++必须在头文件中定义友元函数