Solved

Linking error with a template based class in C++

Posted on 2003-10-21
6
234 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

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

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

This article is meant to give a basic understanding of how to use R Sweave as a way to merge LaTeX and R code seamlessly into one presentable document.
Displaying an arrayList in a listView using the default adapter is rarely the best solution. To get full control of your display data, and to be able to refresh it after editing, requires the use of a custom adapter.
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

776 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