views:

394

answers:

2

I currently have a program where my main code is in a file main.cpp. Main.cpp includes a header file "class.h" that declares a class that is used within main.cpp.

Also in main.cpp I have function declarations that declare the functions I use within main.cpp. The code for these functions is in a separate .cpp file fucntions.cpp. Like main.cpp, functions.cpp also includes class.h as the class type is used within the functions.

class.h contains the class declaration only. The implementation code for class.h is in a separate .cpp file classimplementation.cpp.

It all works fine until I try to make the class in class.h a template class. Then I get linking problems. Research and testing has shown me that this is because the definition of the template class functions needs to reside in class.h with the declaration.

I therefore took the required code out of classimplementations.cpp and put it into class.h. This did solve my original linking issues but instead I get more linking errors that seem to be telling me I am trying to redefine the functions that I moved to into class.h.

This I think is because class.h is being called by main.cpp and again by functions.cpp. Therefore the functions in class.h are being defined twice:

Error 41 error LNK2005: "public: __thiscall RecordPocket::RecordPocket(int)" (??0?$RecordPocket@VT@@@@QAE@H@Z) already defined in classimplementation.obj functions.obj

I know that class implementation code should really be kept out of include files but due to the template class limitation of having to keep the class functions local I appear (in my novice mind) to have no choice.

Has anyone been in this scenario and can offer any advice. I have tried surrounding the functions I moved from classimplementation.cpp to class.h with the standard ifndef CLASSIMP, #define CLASSIMP code and PRAGMA ONCE but neither make any difference.

If all else fails I will move the functions from functions.cpp into main.cpp so that class.h gets called just the once but I’d rather find out what I’m doing wrong as I’m sure it will happen again.

+2  A: 

You could keep the template functions inside the template<> class what{/HERE/};

template<typename T>
class MyTempClass{
     void myFunctions{
      // code here
     }
 }

EDITED: I removed the code corrected by Glen

Arkaitz Jimenez
The inline keyword isn't required.
Glen
If you declare the methods outside the class declaration you NEED inline to avoid redefinition
Arkaitz Jimenez
s/declare the methods/define the methods/
Arkaitz Jimenez
@Arkaitz Jimenez, no you don't. Try it and see
Glen
@Glen, you are right, its not needed, I guess 2 are instantiated and one is removed by the compiler
Arkaitz Jimenez
Must depend on your compiler version... I need it here.
bltxd
Thanks very much, that's sorted. Thanks for your help.
Columbo
Incidentally, can anyone give me a basic explanation of why the template implementation code needs to reside in the same file as the template itself?
Columbo
+1  A: 

I think your problem is revolves around these issues. As you have implied any template function definition (i.e. template function of member function of a template class) needs to be fully expressed in the .h file because when the compiler finds a specific instance of the template it needs to build the function. You figured this out and moved some implementation into your class.h file. Now if the linker find a MyFunction() in more than one module then is just discards one of them a no linker error is reported.

However you can't define the same non-template function in two different modules as this generates the error you are getting above. So I suspect you also moved some non-template functionality into the .h file; thus including it in two separate obj files and generating the linker error. This theory is support by your quoted error message as I note __thiscall RecordPocket::RecordPocket(int) does not appear to be template.

Elemental
Sounds like a good guess, anyway.
David Thornley