我正在努力做到以下几点: 类定义h文件:
template<int Size>
class Sculptor
{
public:
Sculptor();
~Sculptor(void) ;
void Sculp(SculptData* sculpData);
void ToShape(Shape* shape);
int CalculateMesh();
unsigned char sculpture[Size][Size][Size];
}
类定义cpp文件到形状函数(所有其他都相同):
template<int Size>
void Sculptor<Size>::ToShape(Shape* shape){}
用法:
Sculptor<16> sclupt;
Shape shape;
SculptData* data = CreateCircle();
sclupt.Sculp(data);
sclupt.CalculateMesh();
sclupt.ToShape(&shape);
我收到以下错误
你能告诉我问题的根源吗?
答案 0 :(得分:3)
99%的时间LNK2019
意味着您忘记实际完全定义某个函数的主体或您在某处使用过的类。 ?ToShape()
,Sculp()
和CalculateMesh()
的实施位置在哪里?那么构造函数和析构函数
您似乎将实现放入.cpp
文件中。虽然可以理解人们应该将接口与实现分开,但是类模板与非模板完全不同。
编译器实际上并不为模板生成任何机器代码,因为尚未定义所有模板参数。例如,如果不知道成员数组的大小,就无法为Sculptor
生成机器代码。当编译器解析模板定义时,编译器事先不知道Size == 16
。所以你得到链接器错误,因为链接器找不到它的机器代码;它不存在!
对于模板类,您通常会将实现放在模板类声明本身中,因此您可能真的缺少这样的函数定义:
template<int Size>
class Sculptor
{
public:
Sculptor()
{
// implementation
}
// and so on...
Boost库和C ++标准库中的模板定义如下。
附注:使用Size == 16
,您正在创建一个包含4096 unsigned char
s的3x3阵列。虽然这本身并不是问题,但当单个Sculptor
在堆栈上占用至少4096 unsigned char
时,很容易溢出堆栈。
答案 1 :(得分:3)
请记住,模板类的实现必须在使用它的编译单元中可见。特别是,您可能不会将实现放入单独的.cpp文件中(这是非模板类的常见做法),而是应将其放在声明模板的头文件中。
答案 2 :(得分:1)
您忘记编写ToShape,Sculp,CalculateMesh,构造函数和析构函数的代码。实现它们或添加一个虚拟实现,程序将链接。
此外:
unsigned char array sculpture[Size][Size][Size];
是无效的C ++(除非数组是一些无效的定义),你的意思是这个吗?
unsigned char sculpture[Size][Size][Size];
答案 3 :(得分:0)
必须在使用它们的所有翻译单元中完全定义模板 - 您无法将它们链接。这意味着编译器无法找到您正在调用的函数体。