在派生类中重写POD返回类型而不使用const
的示例:
struct B1
{
virtual const int* f();
};
struct D1 : B1
{
int* f() override;
};
像Clang和GCC这样的编译器发出了一个警告:
“虚拟int* D1::f()”的协变返回类型无效
当应用相同的方案但返回类型是某个结构/类时,不会引发警告:
struct S
{
};
struct B2
{
virtual const S* f();
};
struct D2 : B2
{
S* f() override;
};
我在不同的编译器和版本(Clang和GCC)上编译了这个。在没有使用< code>const声明的情况下,当在派生类中返回结构/类指针时,我会预料到类似的警告。
您观察到的行为与标准一致。从草案C 17标准#:
...
8
所以,在你的第二个例子中,上述三个标准都满足了。请注意,8.3是正确的,因为返回的指针不是cv限定的——< code > const 指的是所指向的对象,而不是指针本身。如果改为将基类函数声明为< code > virtual S * const f();那么您拥有的派生类版本将不再有效。此外,派生类函数中的返回类型比基类中的更少cv限定;交换定义,使得基类是< code >虚拟的S * f();且派生的is < code > const S * f()override;也会使其无效。
但是,在您的第一个代码片段中,函数的返回类型不符合8.1标准(int
不是类);因此,为了成为有效的覆盖,它的返回类型必须与基类版本相同。
< sup>#在最新的在线草稿中,文本没有显著变化。