[以下はすべて、Visual Studio 2008 SP1 を使用してテストされています]
C++ では、パラメーター型の const 修飾は関数の型に影響しません (8.3.5/3: 「パラメーター型を変更する cv-qualifier は削除されます」)。
したがって、たとえば、次のクラス階層では、Derived::Foo
overrides Base::Foo
:
struct Base
{
virtual void Foo(const int i) { }
};
struct Derived : Base
{
virtual void Foo(int i) { }
};
C++/CLI で同様の階層を考えてみましょう。
ref class Base abstract
{
public:
virtual void Foo(const int) = 0;
};
ref class Derived : public Base
{
public:
virtual void Foo(int i) override { }
};
次に、のインスタンスを作成するとDerived
:
int main(array<System::String ^> ^args)
{
Derived^ d = gcnew Derived;
}
エラーや警告なしでコンパイルされます。実行すると、次の例外がスローされて終了します。
タイプ 'System.TypeLoadException' の未処理の例外が ClrVirtualTest.exe で発生しました
追加情報: タイプ 'Derived' のメソッド 'Foo' ... には実装がありません。
その例外は、パラメーターの const 修飾がC ++/CLI の関数の型に影響を与える (または、少なくとも何らかの方法でオーバーライドに影響を与える) ことを示しているようです。ただし、 の定義を含む行をコメント アウトするとDerived::Foo
、コンパイラは次のエラーを報告します (main
のインスタンスDerived
がインスタンス化されている行で)。
エラー C2259: 'Derived': 抽象クラスをインスタンス化できません
のパラメーターに const 修飾子を追加するDerived::Foo
か、のパラメーターから const 修飾子を削除するBase::Foo
と、エラーなしでコンパイルおよび実行されます。
パラメーターの const 修飾が関数の型に影響を与える場合、派生クラスの仮想関数のパラメーターの const 修飾が基本クラスの virtual のパラメーターの const 修飾と一致しない場合、このエラーが発生するはずだと思います関数。
Derived::Foo
のパラメータの型をanint
から aに変更するdouble
と、(前述のエラー C2259 に加えて) 次の警告が表示されます。
警告 C4490: 'override': オーバーライド指定子の使用が正しくありません。'Derived::Foo' は基本参照クラス メソッドと一致しません
したがって、私の質問は、事実上、関数パラメーターの const 修飾が C++/CLI の関数の型に影響するかどうかです。もしそうなら、なぜこれはコンパイルされ、エラーや警告がないのはなぜですか? そうでない場合、なぜ例外がスローされるのですか?