[Все последующее было протестировано с использованием Visual Studio 2008 SP1]
В C ++ постоянная квалификация типов параметров не влияет на тип функции (8.3.5 / 3: «Любой cv-квалификатор, модифицирующий тип параметра, удаляется»)
Так, например, в следующей иерархии классов Derived::Foo
переопределяет 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
Дополнительная информация: Метод 'Foo' в типе 'Derived' ... не имеет реализации.
Это исключение указывает на то, что квалификация const параметра влияет на тип функции в C ++ / CLI (или, по крайней мере, влияет на переопределение каким-либо образом). Однако, если я закомментирую строку, содержащую определение Derived::Foo
, компилятор сообщит о следующей ошибке (в строке в main
, где создается экземпляр Derived
):
ошибка C2259: «Производное»: не удалось создать экземпляр абстрактного класса
Если я добавлю квалификатор const к параметру Derived::Foo
или удалим квалификатор const из параметра Base::Foo
, он компилируется и запускается без ошибок.
Я думаю, что если const-квалификация параметра влияет на тип функции, я должен получить эту ошибку, если const-квалификация параметра в виртуальной функции производного класса не совпадает с const-квалификацией параметра в Виртуальная функция базового класса.
Если я изменил тип параметра Derived::Foo
с int
на double
, я получу следующее предупреждение (в дополнение к вышеупомянутой ошибке C2259):
предупреждение C4490: «переопределить»: неправильное использование спецификатора переопределения; Derived :: Foo не соответствует методу базового класса ref
Итак, мой вопрос, фактически, влияет ли постоянная квалификация параметров функции на тип функции в C ++ / CLI? Если так, почему это компилируется и почему нет ошибок или предупреждений? Если нет, то почему выдается исключение?