为什么调用纯虚拟链接器错误而不是编译错误?
Why is calling a pure virtual a linker error rather than a compile error?
这个程序让我有点惊讶:
struct A {
virtual void a()=0;
};
struct B : public A {
void a() {}
};
int main() {
B b;
b.a(); // OK, call B::a()
b.A::a(); // linker error?
}
给我这个错误 (gcc 4.4):
/tmp/ccfOGuBJ.o: In function `main':
test.cc:(.text+0x28): undefined reference to `A::a()'
collect2: ld returned 1 exit status
(clang 7.0.0)
Undefined symbols for architecture x86_64:
"A::a()", referenced from:
_main in test-440cc5.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我预计尝试调用纯函数会给出显式错误,因为它被声明为已删除,而不是隐式错误。 "function not in this translation unit," 和 "function not in any translation unit?"
之间的标准没有区别吗?
应该注意的是,尝试直接调用纯虚拟并没有在§10.4 中解决。
纯虚函数can have a body。因此错误是 link 错误,因为您未能提供正文。
将函数标记为纯虚并不意味着该函数将没有实现。这意味着从你的派生的 类 必须覆盖这个特定的成员函数,或者保持 抽象 。特别是,为 类 提供纯虚函数的实现是完全合法的,该函数派生自您的函数以供继承和使用。
这就是为什么在链接阶段之前无法检测到实现的存在(或不存在)的原因:您可以在单独的翻译单元中提供实现,因此编译器可能不知道它。
这个程序让我有点惊讶:
struct A {
virtual void a()=0;
};
struct B : public A {
void a() {}
};
int main() {
B b;
b.a(); // OK, call B::a()
b.A::a(); // linker error?
}
给我这个错误 (gcc 4.4):
/tmp/ccfOGuBJ.o: In function `main':
test.cc:(.text+0x28): undefined reference to `A::a()'
collect2: ld returned 1 exit status
(clang 7.0.0)
Undefined symbols for architecture x86_64:
"A::a()", referenced from:
_main in test-440cc5.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
我预计尝试调用纯函数会给出显式错误,因为它被声明为已删除,而不是隐式错误。 "function not in this translation unit," 和 "function not in any translation unit?"
之间的标准没有区别吗?应该注意的是,尝试直接调用纯虚拟并没有在§10.4 中解决。
纯虚函数can have a body。因此错误是 link 错误,因为您未能提供正文。
将函数标记为纯虚并不意味着该函数将没有实现。这意味着从你的派生的 类 必须覆盖这个特定的成员函数,或者保持 抽象 。特别是,为 类 提供纯虚函数的实现是完全合法的,该函数派生自您的函数以供继承和使用。
这就是为什么在链接阶段之前无法检测到实现的存在(或不存在)的原因:您可以在单独的翻译单元中提供实现,因此编译器可能不知道它。