来自重载<<的错误链接器错误operator - C ++

时间:2013-04-04 18:28:51

标签: c++ debugging linker

我写了一个小的Timer类来检查代码的性能。源代码可以在http://pastebin.com/i1PX2VPN找到(我稍后会在这里重点介绍重要部分)

现在我遇到了一个非常奇怪的错误:上面链接的代码位于文件Timer.hpp中。我在main.cpp中使用这个文件,它运行得很好。但是,我也想在另一个源文件中使用它,然后,只要我添加一个

  #include <Timer.hpp> 

进入下一个源文件,我收到以下链接器错误:

  ld: duplicate symbol operator<<(std::basic_ostream<char, std::char_traits<char> >&, Timer const&) in /var/folders/XZ/XZ93KWBqG0SR1aCVpTCVQE+++TI/-Tmp-//ccyaHyyU.o and /var/folders/XZ/XZ93KWBqG0SR1aCVpTCVQE+++TI/-Tmp-//ccETAaTw.o
  collect2: ld return 1 as exit status
  make: *** [debugd] Error 1

功能是

 std::ostream& operator<<(std::ostream& os, const Timer& t) {
         return os << std::scientific << std::setw(8)  << std::setprecision(3)
                            << t.timeTotal_ << " \t " << t.timeMin_ << " \t " <<          t.timeMax_;
   }

没有什么太花哨了......再说一遍:只要它只包含在我的main.cpp

中,它才有效

显然,这似乎是运营商的多个定义(?)的问题。但我无法理解为什么或如何解决它。我使用include-guard来保存它不被包含多次。

我已经检查过C ++中是否有其他Timer类 - 我从未听说过的库,显然不是这样(重命名类不会改变任何东西)......

在Timer.hpp中,还定义了另一个类,也有自己的运算符&lt;&lt;超载。我不知道这是否重要,我想我应该提一下

所以......我希望转发你的想法,谢谢

2 个答案:

答案 0 :(得分:7)

您应该将您的函数标记为inline,因为它是一个全局函数,其定义包含在多个翻译单元中。

    inline std::ostream& operator<<(std::ostream& os, const Timer& t) {
//  ^^^^^^
         return os << std::scientific << std::setw(8)  << std::setprecision(3)
               << t.timeTotal_ << " \t " << t.timeMin_ << " \t " 
               << t.timeMax_;
    }

或者,您可以在标题中保留函数的声明,并将定义放在一个.cpp文件中。

如果您想知道为什么包含警卫不会从多个符号定义中保存您,您可能会发现 this Q&A on StackOverflow 非常有用。

答案 1 :(得分:3)

包含防护仅阻止文件在同一个翻译单元中被多次包含。如果将它包含在两个单独编译的.cpp文件中(通常是.cpp个文件),则有多个定义。

将它放在一个实现文件中,在标题中只留下一个声明。