How to define a template class in a .h file and implement it in a .cpp file

To compile this class without any errors, you need to put the template specific declaration in a .cpp file, as shown below:

Template Class Header File
// TestTemp.h
#ifndef _TESTTEMP_H_
#define _TESTTEMP_H_
 
template<class T>
class TestTemp  
{
 
public:
 
    TestTemp();
    void SetValue( T obj_i );
    T Getalue();
 
private:
 
    T m_Obj;
};
#endif
Template Class Source File
// TestTemp.cpp
#include "TestTemp.h"
 
template <class T>
TestTemp<T>::TestTemp()
{
}
template <class T>
void TestTemp<T>::SetValue( T obj_i )
{
 
}
template <class T>
T TestTemp<T>::Getalue()
{
    return m_Obj;
}

Linking Issue

With the above code, after resolving all the compilation errors, you may get some link errors while you create an object of this class in any file other than TestTemp.cpp. Here is some sample code:

Client Source File
// Client.cpp
#include "TestTemp.h"

    :
    TestTemp<int> TempObj;
    :
Link Error
: error LNK2001: unresolved external symbol "public: __thiscall
TestTemp<int>::TestTemp<int>(void)"
(??0?$TestTemp@H@@QAE@XZ)
Reason

When the compiler encounters a declaration of a TestTemp object of some specific type, e.g., int, it must have access to the template implementation source. Otherwise, it will have no idea how to construct the TestTempmember functions. And, if you have put the implementation in a source (TestTemp.cpp) file and made it a separate part of the project, the compiler will not be able to find it when it is trying to compile the client source file. And, #includeing the header file (TestTemp.h) will not be sufficient at that time. That only tells the compiler how to allocate for the object data and how to build the calls to the member functions, not how to build the member functions. And again, the compiler won't complain. It will assume that these functions are provided elsewhere, and leave it to the linker to find them. So, when it's time to link, you will get "unresolved references" to any of the class member functions that are not defined "inline" in the class definition.

Solution

There are different methods to solve this problem. You can select from any of the methods below depending on which is suitable for your application design.

Mehtod 1

You can create an object of a template class in the same source file where it is implemented (TestTemp.cpp). So, there is no need to link the object creation code with its actual implementation in some other file. This will cause the compiler to compile these particular types so the associated class member functions will be available at link time. Here is the sample code:

Template Class Header File
// TestTemp.h
#ifndef _TESTTEMP_H_
#define _TESTTEMP_H_
template<class T>
class TestTemp  
{
public:
    TestTemp();
    void SetValue( T obj_i );
    T Getalue();
 
private:
    T m_Obj;
};
#endif
Template Class Source File
// TestTemp.cpp
#include "TestTemp.h"
 
template <class T>
TestTemp<T>::TestTemp()
{
}
 
template <class T>
void TestTemp<T>::SetValue( T obj_i )
{
}
 
template <class T>
T TestTemp<T>::Getalue()
{
    return m_Obj;
}

// No need to call this TemporaryFunction() function,
// it's just to avoid link error.
void TemporaryFunction ()
{
    TestTemp<int> TempObj;
}
Client Source File
// Client.cpp
#include "TestTemp.h"

    :
        TestTemp<int> TempObj;
        TempObj.SetValue( 2 );
        int nValue = TempObj.Getalue();
    :

The temporary function in "TestTemp.cpp" will solve the link error. No need to call this function because it's global.

Method 2

You can #include the source file that implements your template class in your client source file. Here is the sample code:

Template Class Header File
// TestTemp.h
#ifndef _TESTTEMP_H_
#define _TESTTEMP_H_
 
template<class T>
class TestTemp  
{
public:
    TestTemp();
    void SetValue( T obj_i );
    T Getalue();
private:
    T m_Obj;
};
#endif
Template Class Source File
// TestTemp.cpp
#include "TestTemp.h"

template <class T>
TestTemp<T>::TestTemp()
{
}
 
template <class T>
void TestTemp<T>::SetValue( T obj_i )
{
}
 
template <class T>
T TestTemp<T>::Getalue()
{
   return m_Obj;
}
Client Source File
// Client.cpp
#include "TestTemp.h"
#include "TestTemp.cpp"
              :
        TestTemp<int> TempObj;
        TempObj.SetValue( 2 );
        int nValue = TempObj.Getalue();
              :

Method 3

You can #include the source file that implements your template class (TestTemp.cpp) in your header file that defines the template class (TestTemp.h), and remove the source file from the project, not from the folder. Here is the sample code:

Template Class Header File
// TestTemp.h
#ifndef _TESTTEMP_H_
#define _TESTTEMP_H_
template<class T>
class TestTemp  
{
public:
    TestTemp();
    void SetValue( T obj_i );
    T Getalue();
private:
    T m_Obj;
};
#include "TestTemp.cpp"

#endif
Template Class Source File
// TestTemp.cpp
#include "TestTemp.h"

template <class T>
TestTemp<T>::TestTemp()
{
}
template <class T>
void TestTemp<T>::SetValue( T obj_i )
{
}
 
template <class T>
T TestTemp<T>::Getalue()
{
    return m_Obj;
}
Client Source File
// Client.cpp
#include "TestTemp.h" 
               :
    TestTemp<int> TempObj;
    TempObj.SetValue( 2 );
    int nValue = TempObj.Getalue();
               :

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值