46

I happened to get that already defined in .obj error. This is structure of my project:

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 defined in 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.

As you can see, I'm not double defining/including my class, its included exactly once in 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.

2
  • 8
    Don't include .cpp files, include .h files instead, if you don't have one, make one, apart from that, there is not enough information here to say any more. Commented Mar 14, 2013 at 22:19
  • So you have client.cpp compiled once by itself and once included in main.cpp? Commented Mar 14, 2013 at 22:23

3 Answers 3

73

This is not a compiler error: 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).

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 two separate 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.

Put the definition of your class in a separate client.hpp file which does not contain 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.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" 
Sign up to request clarification or add additional context in comments.

4 Comments

Any ideas what to do, if renaming client.cpp to client.h did not help? I've also moved class definition to client.hpp
@TomášZato You cannot simply rename the file - what purpose would that serve? #include doesn't care what you name your files, it's the content that matters.
@TomášZato See this answer for an explanation of separating your code into .cpp and .h files properly.
What is the point of #include "client.h" inside client.cpp? Also, can you adjust your example to include how one would declare and define free functions (non-class member functions)?
17

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.

Now here's the thing: You are guarding it with #ifndef SOCKET_CLIENT_CLASS, however, each file that has #include "client.cpp" is built independently and as such will find SOCKET_CLIENT_CLASS not yet defined. Therefore it's contents will be included, not #ifdef'd out.

If it contains any definitions at all (rather than just declarations) then these definitions will be repeated in every file where it's included.

Comments

14

I do recomend doing it in 2 filles (.h .cpp) But if u lazy just add inline before the function So it will look something like this

inline void functionX() { } 

more about inline functions:

The inline functions are a C++ enhancement feature to increase the execution time of a program. Functions can be instructed to compiler to make them inline so that compiler can replace those function definition wherever those are being called. Compiler replaces the definition of inline functions at compile time instead of referring function definition at runtime. NOTE- This is just a suggestion to compiler to make the function inline, if function is big (in term of executable instruction etc) then, compiler can ignore the “inline” request and treat the function as normal function.

more info here

1 Comment

In case you have to include .cpp file, this would be a good idea.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.