template class, implementation code causing linking issues - c++

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.

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

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.

Related

VC++ LNK2019 Error I can't seem to fix

So I was writing, as a small project, a stress test. Initially, to save time, I just plopped code in a header file. I decided to organise it a bit, and moved everything to a .cpp file and then wrote the header file, but VS2010 presented me with an LNK2019 that I can't seem to fix.
FSTRESS.cpp (Didn't include code, because I doubt it is relevant; ask if you need it)
FSTRESS.h
Main.cpp
The error:
error LNK2019: unresolved external symbol "public: static void __cdecl FSTRESS::Start(unsigned int,unsigned int,unsigned int)" (?Start#FSTRESS##SAXIII#Z) referenced in function _main C:\Programming\C++\FLOPS_Test\FSTRESS\FSTRESS\main.obj FSTRESS_Mk.II
Any ideas on why this is happening? I'm a bit of a C++ noob.
Thanks for any help :)
Your .cpp file is not defining the same classes as the ones you've declared in the .h, but creating different classes with the same name as those declared in the header. The correct way to do this is:
Header file:
class Foo
{
void Bar();
};
Implementation file:
void Foo::Bar()
{
// Do something
}
Alternately, you can declare the functions inline in the header file itself
class Foo
{
void Bar()
{
// Do something
}
};
In the latter case there's no need to create a separate implementation file. In fact, this is exactly what you're doing in fstress.cpp, but then you provide a duplicate declaration in fstress.h without actually defining that class anywhere.
So, you've actually got two separate definitions of the x86 and FSTRESS classes, one in the header file and one in the .cpp file. You're allowed to do that provided that the definitions are identical, but they aren't -- the one in the .cpp file has a bunch of inline code, which isn't there in the one in the header file. (Look up "one definition rule" for more information about this.)
What you actually want to do is this. Your header file is fine (or, at least, I don't see anything conspicuously wrong with it). The .cpp file should (1) #include the header file, and then (2) provide definitions for the member functions, looking like this:
static void FSTRESS::Start(unsigned aMode, unsigned aTest, unsigned aThreads) {
// code goes here
}
(When you have a source file and a corresponding header file, the source file should always #include the header file. This helps to make sure that if there's an inconsistency it gets caught tidily at compile time. I can't tell whether you were already doing that because the top of FSTRESS.cpp is invisible in your screen captures. It might have been better to post the code as text :-).)
As an aside, don't use names that begin with an underscore. A large portion of the space of such names is "reserved", meaning that the C++ implementation can use them internally and Bad Things can happen if your use clashes with its use. It's best just to avoid them all, because that way you don't have to remember what the exact rule is and neither does anyone else reading your code.
You can't just paste the contents of the class declaration with inlined code from the header file into the .cpp file and expect it to work. The implementation of FSTRESS::Start() needs to look morel like the following when you separate it from the class declaration:
void FSTRESS::Start(unsigned _aMode, unsigned _aTest, unsigned _aThreads)
{
//...
}
Also, you should #include "FSTRESS.h" in the FSTRESS.cpp file so there's exactly on declaration of the class that everyone uses (include the implementation bits in FSTRESS.cpp).

How do you declare a class inline?

My homework assignment is telling me to declare a class inline, but I've only heard of declaring functions inline. What does an inline class declaration do, and how do you achieve it?
I think they are just saying that your classes should go in the header, and for convenience all the class methods should be declared inline in the class itself, instead of putting the class methods out-of-line or into a separate CPP.
It's slightly ambiguous but that's how I'd interpret it.
Comparing functions and classes:
A function can have a declaration and a definition:
ReturnType FunctionName(Parameter1, Parameter2); // a function declaration
ReturnType FunctionName(Parameter1, Parameter2) // a function definition
{
// do something
return ReturnType;
}
The function declaration gives all the information anyone needs who wants to call the function.
The function definition allows the compiler to generate machine code so that when someone calls the function there will be instructions somewhere in the executable that will be called.
This generated code exists only once in the executable. Usually you would put the function definition in a .cpp file (or .c if you're using C, this applies there too), which is compiled and linked into the executable. If that .cpp file isn't linked you will get a linker error saying FunctionName not found or something like that.
If you put the function definition in a header file it is more than likely that the header will be used in multiple places in your system, and included into other .cpp files. This will produce the opposite problem at link time FunctionName already defined in this, that, or the other object file.
So, functions usually aren't defined in header files because the header is usually included in multiple .cpp files so would end up producing duplicated object code.
With classes however it's slightly different. You have two different ways of defining a function for a class. One way is similar to how functions are defined above:
//myleanklass.h
class MyLeanKlass
{
public:
void perform();
};
//myleanklass.cpp
void MyLeanKlass::perform()
{
// Sing, dance, and play the piano
}
Just as with a free function we could have put the definition in the header file, as long as it wasn't included in more than one .cpp file. Otherwise we'd get a similar linker error again void MyLeanKlass::perform already defined ... This scenario is not the norm though. You usually declare classes so that they can be reused through a system. So the header will be included in multiple places and lead to linker errors.
Just to be clear, we could have put the definition in the header file, but not inline. You wouldn't be able to include this header multiple times in your system:
class MyLeanKlass
{
public:
void perform();
};
void MyLeanKlass::perform()
{
// Sing, dance, and play the piano
}
Finally then, we get to the answer to the question. You can define class functions in the header file as long as they are within the class declaration. This is called inline definition. Even if the header is included in multiple .cpp files it won't lead to multiple definitions in compilation units and won't cause linker errors.
//myleanklass.h
class MyLeanKlass
{
public:
void perform()
{
// Sing, dance, and play the piano
}
};
However, there are problems with this approach:
Inlining class functions is likely to make compilation take longer as the compiler will still compile every repeated definition of class functions and only throw away the duplicates at link time.
Making changes to class functions causes a recompilation of any .cpp file which includes it, again leading to longer re-compilation times.
Sometimes it just won't be possible. If a class uses another class and that uses the other class, you're going to have a cyclic dependency and it won't be possible to define everything inline. You can solve that by just putting the problem functions into a separate .cpp file.

Include .cpp file? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Why can templates only be implemented in the header file?
I've been trying around with C++ recently.
At the moment I'm trying to program something I'm sure everone has done at least once: A simple LinkedList class.
The code is done, but I'm somehow failing to compile it. I've been googling and it seems like I'm linking the object files wrong. That's what my code basically looks like:
test.cpp
#include "linkedlist.h"
int main()
{
LinkedList<int> list;
// do something
}
linkedlist.h
template <typename T>
class LinkedList
{
// a lot of function and variable definitions
}
Then there's a .cpp file called linkedlist.cpp which contains all the actual code of the LinkerList class. When trying to compile test.cpp using the following command:
g++ ..\src\test.cpp
I'm getting told that there's an undefined reference to 'LinkedList::LinkedList()'. So I've been thinking that it's being linked wrong as there's more than one .cpp file, so I tried it like this:
g++ -c -Wall -O2 ..\src\test.cpp
g++ -c -Wall -O2 ..\src\linkedlist.cpp
g++ -s test.o linkedlist.o
However, this doesn't change anything. The error messages stay the same.
I've been trying to find some information on the internet, however, it didn't really work out.
You're creating a class template, which has the important caveat that all variable definitions must be placed in the header file so that they're accessible to all translation units during compilation.
The reason is the way that templates work. During compilation, the compiler instantiates template classes based on your class template definition. It isn't enough for it to have access to only the declarations or signatures: it needs to have the entire definition available.
Move all of your method definitions out of the .cpp file and into the .h file, and everything should be fine (assuming that you have, in fact, provided a definition for the default constructor!).
Alternatively, you might be able to get around this by explicitly telling your compiler to instantiate the appropriate template class using something like template class LinkedList<int>, but this really isn't necessary in such a simple case. The primary advantage of this over including all of the definitions in the header file is that it potentially reduces code bloat and speeds up compilation. But it might not be necessary at all, as compilers have gotten a lot smarter at applying appropriate optimizations.
You have split up your class LinkedList and put the declaration in a header and the defintion in a source-file. This does not work for a template. Both have to be in the header.
Template class is like a definition of a rule by which to construct an actual class. The actual classes are created (instantiated) by the compiler wherever there is instantiation of template class. For this reason all the code of template class must be visible to a compiler at that point, and that's why you have to write all the template functions and methods in a header files - because you only include headers to cpp files, only headers are visible to a compiler at that point. You don't include cpp files to another cpp files, and you should never do that.
Correct me if my understanding is wrong.
P. S.
Does C++11 address this issue?
Since LinkedList is a class template, the definitions of its member functions ought to go in a header.
(They don't have to be, strictly speaking, but this is the easiest way to get around the complexities of template instantiation without going totally off-piste with inclusion conventions.)
Oh, and you'd need to take your second build approach anyway; you should link together all .cpp files, or use the -c switch to compile one at a time then link the results together later.
there's an undefined reference to 'LinkedList::LinkedList()'
Have you checked to see if your LinkedList class has a constructor?

C++ including a ".h" file, function duplication confusion

I'm currently writing a program, and couldn't figure out why I got an error (note: I already fixed it, I'm curious about WHY the error was there and what this implies about including .h files).
Basically, my program was structured as follows:
The current file I'm working with, I'll call Current.cc (which is an implementation of Current.h).
Current.cc included a header file, named CalledByCurrent.h (which has an associated implementation called CalledByCurrent.cc). CalledByCurrent.h contains a class definition.
There was a non-class function defined in CalledByCurrent.cc called thisFunction(). thisFunction() was not declared in CalledByCurrent.h since it was not actually a member function of the class (just a little helper function). In Current.cc, I needed to use this function, so I just redefined thisFunction() at the top of Current.cc. However, when I did this, I got an error saying that the function was duplicated. Why is this, when myFunction() wasn't even declared in CalledByCurrent.h?
Thus, I just removed the function from Current.cc, now assuming that Current.cc had access to thisFunction() from CalledByCurrent.cc. However, when I did this, I found that Current.cc did not know what function I was talking about. What the heck? I then copied the function definition for thisFunction() to the top of my CalledByCurrent.h file and this resolved the problem. Could you help me understand this behavior? Particularly, why would it think there was a duplicate, yet it didn't know how to use the original?
p.s - I apologize for how confusing this post is. Please let me know if there's anything I can clear up.
You are getting multiple definitions from the linker - it sees two functions with the same name and complains. For example:
// a.cpp
void f() {}
// b.cpp
void f() {}
then
g++ a.cpp b.cpp
gives:
C:\Users\neilb\Temp\ccZU9pkv.o:b.cpp:(.text+0x0): multiple definition of `f()'
The way round this is to either put the definition in only one .cpp file, or to declare one or both of the functions as static:
// b.cpp
static void f() {}
You can't have two global functions with the same name (even in 2 different translation units). To avoid getting the linker error define the function as static so that it is not visible outside the translation unit.
EDIT
You can use the function in the other .cpp file by using extern keyword. See this example:
//Test.cpp
void myfunc()
{
}
//Main.cpp
extern void myfunc();
int main()
{
myfunc();
}
It will call myfunc() defined in test.cpp.
The header file inclusion mechanism should be tolerant to duplicate header file inclusions.
That's because whenever you simply declare a function it's considered in extern (global) scope (whether you declare it in a header file or not). Linker will have multiple implementation for the same function signature.
If those functions are truely helper functions then, declare them as;
static void thisFunction();
Other way, if you are using the same function as helper then, simply declare it in a common header file, say:
//CalledByCurrent.h (is included in both .cc files)
void thisFunction();
And implement thisFunction() in either of the .cc files. This should solve the problem properly.
Here are some ideas:
You didn't put a header include guard in your header file. If it's being included twice, you might get this sort of error.
The function's prototype (at the top) doesn't match its signature 100%.
You put the body of the function in the header file.
You have two functions of the same signature in two different source files, but they aren't marked static.
If you are using gcc (you didn't say what compiler you're using), you can use the -E switch to view the preprocessor output. This includes expanding all #defines and including all #includes.
Each time something is expanded, it tells you what file and line it was in. Using this you can see where thisFunction() is defined.
There are 2 distinct errors coming from 2 different phases of the build.
In the first case where you have a duplicate, the COMPILER is happy, but the LINKER is complaining because when it picks up all the function definitions across the different source files it notices 2 are named the same. As the other answers state, you can use the static keyword or use a common definition.
In the second case where you see your function not declared in this scope, its because the COMPILER is complaining because each file needs to know about what functions it can use.
Compiling happens before Linking, so the COMPILER cannot know ahead of time whether or not the LINKER will find a matching function, thats why you use declarations to notify the COMPILER that a definition will be found by the LINKER later on.
As you can see, your 2 errors are not contradictory, they are the result of 2 separate processes in the build that have a particular order.

Using non-template functions in template classes

I have a task:
To implement a template vector class (let's name it myvector). I need to use this class in multiple files in my project, so I've put it's declarations in "myvector.h" file, and implementation into "myvector.hpp" file, and then included "myvector.hpp" in "myvector.h" after all the declarations (as described there). However, I have one non-template function in "myvector.hpp". So when I include "myvector.h" file in main file, everything works fine. But when I include "myvector.h" in another one file ("bignum.cpp"), I get a linker error:
error LNK2005: "unsigned int __cdecl gerasimov_dmitry::calculate_capacity(unsigned int)" (?calculate_capacity#gerasimov_dmitry##YAII#Z) already defined in bignum.obj
I understand the causes - "bignum.h" code gets included both in main.cpp and in bignum.cpp file, so compiler doesn't know which one "calculate_capacity" function to use. So, my question is how to fix this situation.
You have to declare the function inline (or alternatively move the definition to a single translation unit).
The problem that you are facing is that if you define the function in the header, and include that header in more than one translation unit, the compiler will generate the function in all translation units.
When the linker tries to generate the program (or library) it finds that the function is defined multiple times and complains about it, as that is a violation of the ODR (One Definition Rule). By marking the function as inline the compiler will flag that function so that when the linker sees the multiple definitions instead of choking it will discard all but one of the definitions.