提问者:小点点

重写方法时,对于非POD类型的“const”指针没有编译器警告


在派生类中重写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声明的情况下,当在派生类中返回结构/类指针时,我会预料到类似的警告。


共1个答案

匿名用户

您观察到的行为与标准一致。从草案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>#在最新的在线草稿中,文本没有显著变化。