编译器说模板类中的方法是未定义的,除非我将其设为虚拟?

时间:2014-01-08 22:46:57

标签: c++ class templates methods virtual

请先阅读此内容:

Storing C++ template function definitions in a .CPP file

这就是我在这里的尝试。

我使用此站点中的第一个方法在cpp文件中定义模板类:

http://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp

看起来像这样:

b.h:

#ifndef B_H_
#define B_H_
class B  
{
public:
    B();
};
#endif

a.h:

#ifndef A_H_
#define A_H_
template<class T>
class A  
{
public:
    A();
    int get();

private:
    int val;
};
#endif

a.cpp

#include "a.h"

template <class T>
A<T>::A()
{
}

template <class T>
int A<T>::get()
{
    return 42;
}

// No need to call this TemporaryFunction() function,
// it's just to avoid link error.
void TemporaryFunction ()
{
    TestTemp<B> TempObj;
}

的main.cpp

#include "a.h"
int main(int argc, char** argv){    
    A<B> ab;
    ab.get();
}

我必须更改为虚拟或我得到:

  

对'A :: get()'

的未定义引用

我不明白这一点。 这只是真实代码的一个示例(太大了)。如果它没有重现,我明天会提供更多细节。

gcc版本4.8.1(Ubuntu / Linaro 4.8.1-10ubuntu9)

1 个答案:

答案 0 :(得分:1)

模板成员可以按需显式实例化或实例化。您没有显式实例化模板,而是通过局部变量导致类型和构造函数的隐式实例化。由于您不使用A<B>::get(),因此编译器不会实例化该函数。

如果函数被标记为virtual,那么它只是通过实例化对象来获取 odr-used (提示:每个虚函数的地址,或类似的一块信息,需要存储在vtable中。)

话虽如此,并且在没有阅读相关文章的情况下,这种方法错误。您不需要创建函数并导致每个成员函数的实例化,而是使用模板的显式实例化。

template class A<B>;   // Explicit instantiation