Solved

Linking error with a template based class in C++

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

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

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.
This is about my first experience with programming Arduino.
An introduction to basic programming syntax in Java by creating a simple program. Viewers can follow the tutorial as they create their first class in Java. Definitions and explanations about each element are given to help prepare viewers for future …
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…

747 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

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now