具有虚拟成员的模板 class:链接器错误
Template class with virtual member: linker error
考虑以下代码。 A 是一个抽象的、通用的class; B既实现又专门化它。这段代码对我来说似乎很正确,但出于某种原因,我最终遇到了奇怪的链接器错误。
template<typename T>
class A {
public:
virtual void f();
};
class B : public A<int> {
public:
void f() {};
};
int main(int argc, char** argv) {
auto b = new B();
return 0;
}
gcc 输出:
/tmp/ccXG2Z8A.o:(.rodata._ZTV1AIiE[_ZTV1AIiE]+0x10): undefined reference to `A<int>::foo()'
collect2: error: ld returned 1 exit status
clang 输出:
/tmp/l2-2a09ab.o: In function `main':
l2.cpp:(.text+0x35): undefined reference to `operator new(unsigned long)'
/tmp/l2-2a09ab.o:(.rodata._ZTI1AIiE[_ZTI1AIiE]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
/tmp/l2-2a09ab.o:(.rodata._ZTI1B[_ZTI1B]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/tmp/l2-2a09ab.o:(.rodata._ZTV1AIiE[_ZTV1AIiE]+0x10): undefined reference to `A<int>::foo()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
A 不是摘要 class。你应该这样做:
virtual void f() = 0;
使其成为纯虚函数
根据 gcc 输出,我假设您的函数被调用 foo
而不仅仅是 f
。
问题是 class A
不是抽象的,因为您还没有这样声明它的方法。您可以这样做:
virtual void foo() = 0;
但是你忘记了= 0
,所以链接器不知道这个方法是抽象的,因此正在寻找一个不存在的函数体。
考虑以下代码。 A 是一个抽象的、通用的class; B既实现又专门化它。这段代码对我来说似乎很正确,但出于某种原因,我最终遇到了奇怪的链接器错误。
template<typename T>
class A {
public:
virtual void f();
};
class B : public A<int> {
public:
void f() {};
};
int main(int argc, char** argv) {
auto b = new B();
return 0;
}
gcc 输出:
/tmp/ccXG2Z8A.o:(.rodata._ZTV1AIiE[_ZTV1AIiE]+0x10): undefined reference to `A<int>::foo()'
collect2: error: ld returned 1 exit status
clang 输出:
/tmp/l2-2a09ab.o: In function `main':
l2.cpp:(.text+0x35): undefined reference to `operator new(unsigned long)'
/tmp/l2-2a09ab.o:(.rodata._ZTI1AIiE[_ZTI1AIiE]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
/tmp/l2-2a09ab.o:(.rodata._ZTI1B[_ZTI1B]+0x0): undefined reference to `vtable for __cxxabiv1::__si_class_type_info'
/tmp/l2-2a09ab.o:(.rodata._ZTV1AIiE[_ZTV1AIiE]+0x10): undefined reference to `A<int>::foo()'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
A 不是摘要 class。你应该这样做:
virtual void f() = 0;
使其成为纯虚函数
根据 gcc 输出,我假设您的函数被调用 foo
而不仅仅是 f
。
问题是 class A
不是抽象的,因为您还没有这样声明它的方法。您可以这样做:
virtual void foo() = 0;
但是你忘记了= 0
,所以链接器不知道这个方法是抽象的,因此正在寻找一个不存在的函数体。