【发布时间】:2011-03-27 14:51:14
【问题描述】:
今天我在我的一个类中重载了
#ifndef TERMINALLOG_HH
#define TERMINALLOG_HH
using namespace std;
class Terminallog {
public:
Terminallog();
Terminallog(int);
virtual ~Terminallog();
template <class T>
Terminallog &operator<<(const T &v);
private:
};
#endif
如您所见,我在头文件中定义了重载运算符,然后在我的 .cc 文件中继续实现它:
//stripped code
template <class T>
Terminallog &Terminallog::operator<<(const T &v) {
cout << endl;
this->indent();
cout << v;
return *this;
}
//stripped code
之后我使用我的新类创建了一个 main.cpp 文件:
#include "inc/terminallog.hh"
int main() {
Terminallog clog(3);
clog << "bla";
clog << "bla";
return 0;
}
然后我继续编译:
g++ src/terminallog.cc inc/terminallog.hh testmain.cpp -o test -Wall -Werror
/tmp/cckCmxai.o: In function `main':
testmain.cpp:(.text+0x1ca): undefined reference to `Terminallog& Terminallog::operator<< <char [4]>(char const (&) [4])'
testmain.cpp:(.text+0x1de): undefined reference to `Terminallog& Terminallog::operator<< <char [4]>(char const (&) [4])'
collect2: ld returned 1 exit status
砰!一个愚蠢的链接器错误,我仍然不知道它来自哪里。我玩了一下,发现将重载运算符的实现放在头文件中可以解决所有问题。现在我比以前更困惑了。
为什么我不能将重载运算符的实现放在我的 .cc 文件中?为什么我把它放在我的头文件中运行平稳?
先谢谢了
ftiaronsem
【问题讨论】:
-
链接器错误绝不是愚蠢的 - 它们与编译器错误一样提供信息。
-
@ftiaronsem:顺便说一句 - 不要将
using namespace std;放在头文件中 - 您可以将其放在 'cc' 文件中,然后根据需要在头文件中使用std::限定符。 -
@quamrana:感谢您的评论,我可以做到。但为什么它被认为是不好的做法?
-
@ftiaronsem:它在全局命名空间中包含
std命名空间,用于该标头的所有客户端以及您之后包含的任何标头。例如,看到这个答案:stackoverflow.com/questions/1265039/using-std-namespace/…