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