[以下所有内容均使用 Visual Studio 2008 SP1 进行了测试]
在 C++ 中,参数类型的 const 限定不影响函数的类型(8.3.5/3:“删除任何修改参数类型的 cv-qualifier”)
因此,例如,在以下类层次结构中,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”类型的未处理异常
附加信息:“Derived”类型中的方法“Foo”...没有实现。
该异常似乎表明参数的 const 限定确实会影响 C++/CLI 中函数的类型(或者,至少它会以某种方式影响覆盖)。但是,如果我注释掉包含定义的行Derived::Foo
,编译器会报告以下错误(在main
实例化的行上Derived
):
错误 C2259:“派生”:无法实例化抽象类
如果我将 const 限定符添加到参数 ofDerived::Foo
或从参数中删除 const 限定符Base::Foo
,它将编译并运行而没有错误。
我认为如果参数的 const 限定影响函数的类型,如果派生类虚函数中参数的 const 限定与基类 virtual 中参数的 const 限定不匹配,我应该得到这个错误功能。
如果我将Derived::Foo
's 参数的类型从 anint
更改为 a double
,我会收到以下警告(除了上述错误,C2259):
警告 C4490:“覆盖”:错误使用覆盖说明符;'Derived::Foo' 与基 ref 类方法不匹配
所以,我的问题是,函数参数的 const 限定是否会影响 C++/CLI 中函数的类型?如果是这样,为什么会编译,为什么没有错误或警告?如果不是,为什么会抛出异常?