这是一个带有未定义方法的类。似乎编译器允许构造此类的实例,只要从未调用未定义的成员函数:
struct A {
void foo();
};
int main() {
A a; // <-- Works in both VC2013 and g++
a.foo(); // <-- Error in both VC2013 and g++
}
这是一种类似的情况,但涉及继承。子类Bar
扩展基类Foo
。Foo
定义一个方法g()
。Bar
声明了同名方法但没有定义它:
#include <iostream>
struct Foo {
void g() { std::cout << "g\n"; }
};
struct Bar : Foo {
void g();
};
int main() {
Bar b; // Works in both VC2013 and g++
b.Foo::g(); // Works in both VC2013 and g++
b.g(); // Error in both VC2013 and g++
}
这是上述的一种变体。这里唯一的区别g()
是virtual
两者Foo
和Bar
:
#include <iostream>
struct Foo {
virtual void g() { std::cout << "g\n"; }
};
struct Bar : Foo {
virtual void g();
};
int main() {
Bar b; // Works in g++. But not in VC2013, which gives
// 'fatal error LNK1120: 1 unresolved externals'
b.Foo::g(); // Works in g++, but VC2013 already failed on b's construction
b.g(); // Error in g++, but VC2013 already failed on b's construction
}
有关 VC2013 和 g++ 之间不同行为的对比,请参见代码注释。
- 哪个编译器是正确的,如果有的话?
- 为什么VC2013的编译器有
virtual
关键字的版本和没有关键字的版本有一些不同的抱怨virtual
? - 是否总是允许未使用的未定义方法?如果不是,在哪些情况下是不允许的?
- 即使不提供定义
Bar
, 的声明是否也g()
算作覆盖?Bar