[Все нижеперечисленное было протестировано с использованием 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;
}
он компилируется без ошибок или предупреждений. Когда я запускаю его, он выдает следующее исключение, а затем завершает работу:
В ClrVirtualTest.exe возникло необработанное исключение типа «System.TypeLoadException».
Дополнительная информация: Метод "Foo" типа "Производный"... не имеет реализации.
Это исключение указывает на то, что квалификация 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
Итак, мой вопрос заключается в том, влияет ли квалификация const параметров функции на тип функции в C++/CLI? Если да, то почему это компилируется и почему нет ошибок или предупреждений? Если нет, то почему выбрасывается исключение?