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

Compiler says method in template class is undefined unless I make it virtual?

本文关键字:非我 虚拟 未定义 方法 编译器      更新时间:2023-10-16

请先阅读以下内容:

C++模板函数定义存储在 .CPP 文件

这就是我在这里尝试的。

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

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

它看起来像这样:

BH :

#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

答.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;
}

主.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)

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

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

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

template class A<B>;   // Explicit instantiation