Click here to Skip to main content
Click here to Skip to main content

Splitting Up Class Template Declarations and Definitions

, 29 Nov 2012 CPOL
Rate this:
Please Sign up or sign in to vote.
Tips on how to declare a class template in a header file and define a class template in a source file.

Introduction 

I think it's a bit sloppy to define a class in a header file, so I decided that I wanted to split up my class template into a header file (the class template declaration) and source file (the class template definition). I soon realized the issue here: it would need circular dependency to define itself (which I will explain). There's a quick and safe way to do this, and this is how I figured it out. First, you need to define the class. Here's the example we'll be using (I removed the documentation and code so it's just bare bones). As you can see, it's just the two separate files (the header file and source file).

#ifndef INPUT_H_
#define INPUT_H_

template <class T>
class Input
{
public: // Constructors:
    Input(T test);
};
#endif /* INPUT_H_ */
template <class T>
Input<T>::Input(T stream) 
{
}

Including Class Member Definitions 

The first error that arises is that the class template is searching for a constructor definition (which is not in the header file as you can see). To fix this, we create a link to the source file (just within the preprocessor definition check body): #include "Input.cpp". Now, the header file links to the source file and can successfully obtain the constructor definition.

Including Class Declarations

This is where a second problem arises; the class isn't defined in the source file (because we didn't include it and source files include resources using one-way, linear dependency ... so the header information did not get passed to the source file). Well, that's no problem. We'll just include the header file in the source file to get the class definition. At the top of the file, we add #include "Input.h".

Solving the Duplicate Definition Error

This is where we fall into a loop. The source file includes the input header file... which includes the source file. This leaves the source file being compiled twice (which throws an error - the constructor has been defined twice). Luckily... the class template doesn't load resources from the source file (remember, it's one-way, linear dependency). All it includes is the link to the template definition. We can get away with compiling the header file first (as long as the #include "Input.cpp" is there). So finally, we can fix this by adding a preprocessor definition check to stop the compiler's second attempt at compiling the source file (as seen below).

#ifndef INPUT_H_
#define INPUT_H_

template <class T>
class Input
{
public: // Constructors:
    Input(T test);
};

#include "Input.cpp"
#endif /* INPUT_H_ */
#ifndef INPUT_CPP_
#define INPUT_CPP_
#include "Input.h"

template <class T> 
Input<T>::Input(T stream) 
{
} 
#endif /* INPUT_CPP_ */

Conclusion

That's it. The class template is now being declared in the header file and defined in the source file. First, we included the class member definitions so the template was defined; then, we included the class declaration so the source file could define the class; and finally, we solved our duplicate definition error by using pre-processor directives.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Gareth Jensen
Student Saddleback Community College
United States United States
No Biography provided

Comments and Discussions

 
SuggestionCan't quite agree with you PinmemberBigDaveDev5-Apr-13 2:04 
GeneralRe: Can't quite agree with you PinmemberGareth Jensen5-Apr-13 20:36 
GeneralRe: Can't quite agree with you PinmemberBigDaveDev5-Apr-13 21:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141223.1 | Last Updated 29 Nov 2012
Article Copyright 2012 by Gareth Jensen
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid