Solved

Linking error with a template based class in C++

Posted on 2003-10-21
6
235 Views
Last Modified: 2010-04-17
Hi All,

I have been facing a peculiar linking error with my template class on both GNU C++
compiler and Visual C++ compiler. Can anybody help me in this regard. It is a part
of my project work and any help will be highly appreciated. Error encountered and source codes are given below

Thanks in advance

Siddhartha



Compilation
-----------
g++ -c atmplane.cpp   -> creates file atmplane.o
g++ -c test.cpp       -> creates file test.o

Linking
-------

g++ -o atmplane.o test.o
g++ -o test.o atmplane.o

Both these commands give following error
----------------------------------------

test.o: In function `main':
test.o(.text+0x12): undefined reference to `ATMPlane<int>::ATMPlane(int, int)'
test.o(.text+0x26): undefined reference to `ATMPlane<int>::~ATMPlane(void)'
collect2: ld returned 1 exit status



A Win32 console application created in Visual C++ 6.0 with the same files also
give the same linking error


--------------------Configuration: Test - Win32 Debug--------------------
Compiling...
atmplane.cpp
test.cpp
Linking...
test.obj : error LNK2001: unresolved external symbol
"public: __thiscall ATMPlane<int>::~ATMPlane<int>(void)" (??1?$ATMPlane@H@@QAE@XZ)
test.obj : error LNK2001: unresolved external symbol
"public: __thiscall ATMPlane<int>::ATMPlane<int>(int,int)" (??0?$ATMPlane@H@@QAE@HH@Z)
Debug/Test.exe : fatal error LNK1120: 2 unresolved externals
Error executing link.exe.

Test.exe - 3 error(s), 0 warning(s)

-----------------------------------------------------------------------------

---------------------------
Source codes are as follows
---------------------------


/******** File Name - atmplane.h *************/

#ifndef ATM_PLANE_H

#define ATM_PLANE_H

template <class T> class ATMPlane
{
      private :
            int _iNum1, _iNum2;
            T _tObj;
      public:
            ATMPlane(int, int);
            ~ATMPlane();
};

#endif


/******** File Name - atmplane.cpp *************/

#include "atmplane.h"

template <class T> ATMPlane<T>::ATMPlane(int iNum1, int iNum2)
{
      _iNum1 = iNum1;
      _iNum1 = iNum2;
}

template <class T> ATMPlane<T>::~ATMPlane()
{
      
}

/******** File Name - test.cpp *************/

#include "atmplane.h"

int main(int argc, char *argv[])
{
      ATMPlane<int> atm(3,2);      
      return 0;
}
0
Comment
Question by:siddhartha_ghosh
  • 3
6 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 250 total points
ID: 9597400
Template class implementation should be kept entirely in h-file. You have two ways:
1) Place function bodies inside of class definitions
2) Place function bodies after class definition in the same h-file.

Template class functions cannot be implemented in separate cpp file.

This happens because C++ compiler makes actual template compilation only when template is instantiated. When this happens, compiler needs all template functions to be available. They shouls be defined in h-file or in the same cpp file. Only linker has access to different cpp file.

In your case, atmplane.cpp doesn't produce any real code (because it is created by compiler only when template is instantiated).
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 9597419
By the way, this is a reason template classes cannot be kept in Dll and lib files. All template libraries (like STL, ATL) are supplied in h-files, so that client has full access to their source code. I don't think that library writers like this, but this is only way.

So, remove atmplane.cpp class and add all it's code to atmplane.h:

#ifndef ATM_PLANE_H

#define ATM_PLANE_H


template <class T> class ATMPlane
{
    private :
         int _iNum1, _iNum2;
         T _tObj;
    public:
         ATMPlane(int, int);
         ~ATMPlane();
};

template <class T> ATMPlane<T>::ATMPlane(int iNum1, int iNum2)
{
    _iNum1 = iNum1;
    _iNum1 = iNum2;
}

template <class T> ATMPlane<T>::~ATMPlane()
{
   
}

#endif
0
 
LVL 48

Expert Comment

by:AlexFM
ID: 10319470
I think my answer is OK.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show, step by step, how to integrate R code into a R Sweave document
Does the idea of dealing with bits scare or confuse you? Does it seem like a waste of time in an age where we all have terabytes of storage? If so, you're missing out on one of the core tools in every professional programmer's toolbox. Learn how to …

827 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question