哪里放超载<<代码?

cor*_*tin 3 c++ operator-overloading

我试图重载流操作符<<,对于已经有toString()函数返回字符串的类Foo ,使用以下代码:

std::ostream &operator<<( std::ostream &flux, Foo const& foo )
{
    flux <<  foo.toString(); 
    return flux;
}
Run Code Online (Sandbox Code Playgroud)

为了在main.cpp文件中使用它

我的问题是:在哪里放一段代码?

  • 如果我把它放在main.cpp它使用之前,它运行良好,但我可能想在其他文件中使用它.
  • 如果我把它放入foo.cpp,我得到一个'没有这样的功能'错误:

    src/main.cpp:77: error: no match for ‘operator<<’ in ‘std::cout << foo’
    
    Run Code Online (Sandbox Code Playgroud)

    这是有道理的,因为代码不包含在main.cpp文件中

  • 如果我将它放在foo.h类头,外部类声明中,我会得到一个"多重定义"错误:

    foo.o: In function `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Foo const&)':
    foo.cpp:(.text+0x0): multiple definition of `operator<<(std::basic_ostream<char, std::char_traits<char> >&, Matrix const&)'
    bar.o:bar.cpp:(.text+0x0): first defined here
    
    Run Code Online (Sandbox Code Playgroud)

    foo.h头的确包括在不同的类/文件,但有一个ifdef的后卫,所以我不明白这一点.

那我该怎么办?

Luc*_*ore 11

有多种选择:

在标题中声明它,然后在其中Foo定义它Foo.cpp.

//foo.h
class Foo
{};
std::ostream &operator<<( std::ostream &s, Foo const& foo );

//foo.cpp
#include "foo.h"
std::ostream &operator<<( std::ostream &s, Foo const& foo )
{
    return s;
}
Run Code Online (Sandbox Code Playgroud)

将其定义为friend类定义内部.

//Foo.h
class Foo
{
   friend std::ostream &operator<<( std::ostream &s, Foo const& foo )
   {
      return s;
   }
};
Run Code Online (Sandbox Code Playgroud)

在类定义之外的标题中定义它,并将其标记为inline阻止多重定义.

//Foo.h
class Foo
{
};

inline std::ostream &operator<<( std::ostream &s, Foo const& foo )
{
   return s;
}
Run Code Online (Sandbox Code Playgroud)


Seb*_*ach 5

将重载的原型放在类声明中,将其实现放在实现中Foo(或者如果需要inline,将其放在Foo声明中)。

所以要么:

// foo.h
#ifndef FOO_H_ASDSADKJSLADJL
#define FOO_H_ASDSADKJSLADJL
class Foo {
};
std::ostream& operator<< (std::ostream &, Foo const &);
#endif // FOO_H_ASDSADKJSLADJL
Run Code Online (Sandbox Code Playgroud)
// foo.cpp
#include "foo.h"
....
std::ostream& operator<< (std::ostream &os, Foo const &) {
    ....
    return os;
}
Run Code Online (Sandbox Code Playgroud)

或者

#ifndef FOO_H_ASDSADKJSLADJL
#define FOO_H_ASDSADKJSLADJL
class Foo {
};
inline std::ostream& operator<< (std::ostream &os, Foo const &) {
    ....
    return os;
}
#endif // FOO_H_ASDSADKJSLADJL
Run Code Online (Sandbox Code Playgroud)

编译器未找到它的错误是缺少重载的原型。

  • 我认为投反对票是因为你的第一个答案中有“十九个以上的字符”。 (2认同)