C++ 已在 .obj 中定义 - 没有双重包含
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15421254/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Already defined in .obj - no double inclusions
提问by Tomá? Zato - Reinstate Monica
I happened to get that already defined in .obj error. This is structure of my project:
我碰巧在 .obj 错误中已经定义了它。这是我的项目的结构:
main.cpp
主程序
#include "main.h";
main.h
主文件
#include <iostream>
#include <string>
#include <sstream>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include "client.cpp"
client.cpp
客户端
#ifndef SOCKET_CLIENT_CLASS
#define SOCKET_CLIENT_CLASS
#ifndef BOOST_ASIO_HPP
#include <boost/asio.hpp>
#endif
/*CLASS DEFINITION HERE*/
#endif
This is what compiler is complaining about:
这就是编译器抱怨的:
main.obj : error LNK2005: "public: bool __thiscall SocketClient::read(int,char *)" (?read@SocketClient@@QAE_NHPAD@Z) already definedin client.obj
main.obj : error LNK2005: "public: bool __thiscall SocketClient::read(int,char *)" (?read@SocketClient@@QAE_NHPAD@Z)已在 client.obj 中定义
Note it is complaining about my class, not boost. One interesting thing is, that when I remove #include <boost/asio.hpp>
from client.cpp, I get errors thouhg it is included in main.h too.
请注意,它是在抱怨我的课程,而不是提升。一件有趣的事情是,当我#include <boost/asio.hpp>
从client.cpp 中删除时,我收到错误消息,它也包含在 main.h 中。
As you can see, I'm not double defining/including my class, its included exactly oncein main.h. So what's going on here?
I have read this answer, but it was no help, since it expects double inclusions. Take this fact into osideration before voting for duplicate, because this simply means beheading me without mercy.
正如你所看到的,我没有双重定义/包括我的类,它在main.h中只包含一次。那么这里发生了什么?
我已经阅读了这个答案,但它没有帮助,因为它需要双重包含。在投票给重复之前考虑这个事实,因为这只是意味着毫不留情地斩首我。
回答by Andy Prowl
This is not a compilererror: the error is coming from the linker. After compilation, the linker will merge the object files resulting from the compilation of each of your translation units (.cpp
files).
这不是编译器错误:错误来自链接器。编译后,链接器将合并由每个翻译单元(.cpp
文件)编译产生的目标文件。
The linker finds out that you have the same symbol defined multiple times in different translation units, and complains about it (it is a violation of the One Definition Rule).
链接器发现你在不同的翻译单元中多次定义了相同的符号,并抱怨它(这违反了一个定义规则)。
The reason is most certainly that main.cpp
includes client.cpp
, and both these files are individually processed by the compiler to produce twoseparate object files. Therefore, all the symbols defined in the client.cpp
translation unit will be defined also in the main.cpp
translation unit. This is one of the reasons why you do not usually #include
.cpp
files.
原因肯定是main.cpp
包含client.cpp
,并且这两个文件都由编译器单独处理以生成两个单独的目标文件。因此,client.cpp
翻译单元中定义的所有符号也将在翻译单元中定义main.cpp
。这是您通常不归档的原因之一#include
.cpp
。
Put the definition of your class in a separate client.hpp
file which does notcontain also the definitions of the member functions of that class; then, let client.cpp
and main.cpp
include that file (I mean #include
). Finally, leave in client.cpp
the definitions of your class's member functions.
将类的定义放在一个单独的client.hpp
文件中,该文件不包含该类的成员函数的定义;然后,让client.cpp
并main.cpp
包含该文件(我的意思是#include
)。最后,保留client.cpp
类成员函数的定义。
client.h
客户端.h
#ifndef SOCKET_CLIENT_CLASS
#define SOCKET_CLIENT_CLASS
#ifndef BOOST_ASIO_HPP
#include <boost/asio.hpp>
#endif
class SocketClient // Or whatever the name is...
{
// ...
bool read(int, char*); // Or whatever the name is...
// ...
};
#endif
client.cpp
客户端
#include "Client.h"
// ...
bool SocketClient::read(int, char*)
{
// Implementation goes here...
}
// ... (add the definitions for all other member functions)
main.h
主文件
#include <iostream>
#include <string>
#include <sstream>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include "client.h"
// ^^ Notice this!
main.cpp
主程序
#include "main.h"
回答by wilsonmichaelpatrick
You probably don't want to do this:
你可能不想这样做:
#include "client.cpp"
A *.cpp file will have been compiled by the compiler as part of your build. By including it in other files, it will be compiled again (and again!) in every file in which you include it.
*.cpp 文件将作为构建的一部分由编译器编译。通过将它包含在其他文件中,它将在包含它的每个文件中再次编译(并且再次!)。
Now here's the thing:You are guarding it with #ifndef SOCKET_CLIENT_CLASS
, however, each file that has #include "client.cpp"
is built independentlyand as such will find SOCKET_CLIENT_CLASS
not yet defined. Therefore it's contents will be included, not #ifdef'd out.
现在事情是这样的:你用 来保护它#ifndef SOCKET_CLIENT_CLASS
,但是,每个拥有的文件#include "client.cpp"
都是独立构建的,因此会发现SOCKET_CLIENT_CLASS
尚未定义。因此它的内容将被包括在内,而不是#ifdef'd。
If it contains any definitions at all (rather than just declarations) then these definitions will be repeated in every file where it's included.
如果它包含任何定义(而不仅仅是声明),那么这些定义将在包含它的每个文件中重复。
回答by MOHAMMAD WASEEM
This is one of the method to overcome this issue.
这是克服这个问题的方法之一。
- Just put the prototype in the header files and include the header files in the .cpp files as shown below.
- 只需将原型放在头文件中,并将头文件包含在 .cpp 文件中,如下所示。
client.cpp
客户端
#ifndef SOCKET_CLIENT_CLASS
#define SOCKET_CLIENT_CLASS
#ifndef BOOST_ASIO_HPP
#include <boost/asio.hpp>
#endif
class SocketClient // Or whatever the name is... {
// ...
bool read(int, char*); // Or whatever the name is...
// ... };
#endif
client.h
客户端.h
bool SocketClient::read(int, char*)
{
// Implementation goes here...
}
main.cpp
主程序
#include <iostream>
#include <string>
#include <sstream>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
#include "client.h"
// ^^ Notice this!
main.h
主文件
int main()