1
The source code below is an abstraction of a code in production. However, it is real, and the facts reported below are applicable to it.
The code compiles usually in GCG (linux), but in Visual Studio 2017 (windows), I get the error:
LNK2005 "public: int __cdecl XTEST::Mt::soma(int,int)" (??soma@Mt@XTEST@@QEAHHH@Z) already defined in ...
main.cpp
#include "teste.cpp"
#include <stdio.h>
int main(){
getchar();
XTEST::Mt *t = new XTEST::Mt();
printf("\n\nretorno = %d\n\n", t->soma(3, 5));
delete t;
return 0;
}
cpp testing.
#pragma once
#ifndef TESTE_H
#define TESTE_H
#include "mhead.cpp"
#endif
mhead. h
#pragma once
#ifndef MT_H
#define MT_H
namespace XTEST {
class Mt {
public:
int soma(int i, int d);
};
}
#endif
mhead.cpp
#pragma once
#ifndef MT_CPP
#define MT_CPP
#include "mhead.h"
namespace XTEST {
int Mt::soma(int i, int d) {
return i + d;
}
}
#endif
I’m a beginner in C++ - especially VS - but I know that ". h" should not - preferably - contain implementations, only statements. Thus in the above case the ". h" contains only the class declaration, and the entire implementation is placed in the ". cpp".
You may wonder why I have the cpp testing.. This is because the program has a high amount of "modules". And in the program under production, all the features of a module are nested in a file ".cpp". These in turn must include the dependencies. Therefore, the existence of the "cpp testing." is to maintain the equivalence of this code with the real one, which was omitted because of the size (more than 10,000 lines).
This ends up making the implementation exists in the objects mhead.obj, obj test. and main obj., duplicate. As far as I know this is the reason for the above error.
However, it is impossible to compile a code without including the ".cpp" - which contains the implementations. How to include both the ".h" as to the ".cpp", allowing, however, the entire program to access the functionalities of the same?
NOTE: ". cpp" includes ". h" because ". cpp" demands the presence of the statements; however ". h" does not include ". cpp" because ". h" can make use of external implementation, such as ". dll".
Thank you.
EDITION 1:
The @lacobus answer is right (grateful) and solves the problem, but NOT conclusively. The above question includes the (implicit) need for GCC compilation, which may not have been clear, and the answer whether it had this objective was also unclear. A specific question for compatibility has been opened here.
Thanks for your help. I realized that in no time is included the file ". cpp", this leads me to deduce that VS does the automatic inclusion of it. However, the doubt arises, how to avoid the "automatic" inclusion of ". cpp" by VS, when the wish is that implementations are imported from dll? I have used macros to automatically put "dllimport" before the functions. But if there is automatic inclusion of ". cpp", this would not generate redundancy?
– guinalz