これは未定義のメソッドを持つクラスです。コンパイラは、未定義のメンバー関数が呼び出されない限り、このクラスのインスタンスを構築できるようです:
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()です:virtualFooBar
#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