C ++ - 必须在头文件中定义好友函数吗?

时间:2011-12-04 05:03:25

标签: c++ operator-overloading header-files friend

我想重载运算符<<在我的一个课程中。 签名是这样的:

friend std::ostream& operator<<(std::ostream& os, const Annuaire& obj)

当我尝试在.cpp文件中定义它时,它表示运算符&lt;&lt;确切地说需要1个参数,但是,当我在.h中定义它时,它编译/工作正常。

这是我在.cpp文件中定义它的方式:

std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){ // ... }

是否与需要在头文件中定义的朋友功能有关?

5 个答案:

答案 0 :(得分:12)

它可以在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
}

答案 1 :(得分:9)

问题在于你定义它的方式。它不是该类的成员,它只是该类的朋友。您需要删除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),以及另外两个参数({{1 }和os)。

答案 2 :(得分:5)

如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;
}

答案 3 :(得分:3)

朋友函数,即使它们似乎在类中声明,也不是成员函数,而是名称空间级函数(在封闭的命名空间中)。在您的代码中,您正确声明了友元函数,但您尝试将其定义为类的成员函数:

std::ostream& Annuaire::operator<<(std::ostream& os, const Annuaire& obj){

该定义适用于Annuaire的成员函数,称为operator<<,它带有两个参数,这两个参数无效,因为operator<<可以通过以下两种方式之一重载:自由函数采用两个参数(左手侧和右手侧)或作为类的成员函数,出现在表达式的lhs中,采用rhs类型的参数。在这种特殊情况下,由于lhs是std::ostream并且您无法修改它,因此您只能选择使用自由函数:

std::ostream& operator<<(std::ostream& os, const Annuaire& obj)

答案 4 :(得分:2)

没有这样的限制;你可能只是写错了。应该是这样的:

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;
}
相关问题