2

$10.3/5

“覆盖函数的返回类型应与被覆盖函数的返回类型相同或与函数的类协变。如果函数 D::f 覆盖函数 B::f,则函数的返回类型如果它们满足以下标准,则它们是协变的:

— 两者都是类的指针或类的引用 98)

— B::f 的返回类型中的类与 D::f 的返回类型中的类是同一类,或者是 D 的返回类型中的类的明确且可访问的直接或间接基类: :F

指针或引用都具有相同的 cv 限定,并且D::f 的返回类型中的类类型具有与 B::f 的返回类型中的类类型相同或更少的 cv 限定。

struct A{};
struct B : A{};

struct X{
    virtual const A * const f(){return 0;}
};

struct Y : X{
    virtual const B * volatile f(){return 0;}
};

int main(){
    Y b;
    X &r = b;
    r.f();
}

我写了上面的实验代码,发现 Comeau 的错误/警告不一致。第 9 行中的警告似乎表明返回类型中的 cv 限定符没有意义。正是这个原因导致代码格式错误。

"ComeauTest.c", line 5: warning: type qualifier on return type is meaningless
virtual const A * const f(){return 0;}
                  ^

"ComeauTest.c", line 9: warning: type qualifier on return type is meaningless
virtual const B * volatile f(){return 0;}
                  ^

"ComeauTest.c", line 9: error: return type is not identical to nor covariant with
      return type "const A *const" of overridden virtual function function
      "X::f"
virtual const B * volatile f(){return 0;}
                           ^

所以问题是,Comeau 在第 9 行发出“警告”信息是否正确?我知道这是一种实现定义的行为,Comeau 只是想表现得很好。但在这种情况下,它充其量是令人困惑的。

4

1 回答 1

2

第 5 行和第 9 行关于“返回类型的类型限定符没有意义”的警告是因为非类类型右值永远不会被 cv 限定。

由于按值返回的函数的结果是右值并且指针是非类类型,因此返回的指针不是 cv 限定的,即使返回类型表明它是。

此警告与协方差无关。以下函数将导致相同的警告:

int* volatile f() { return 0; }

至于 10.3/5 的引用文本:

指针或引用都具有相同的 cv 限定

这是指返回类型的顶级限定(即volatilein const int* volatile)。虽然顶级限定是没有意义的,但它确实会影响函数的类型,所以鉴于f上面的声明,这个片段是不正确的:

int* (*q)() = f; // error:  can't convert int* volatile (*)() to int* (*)()

同样,如果派生类成员函数中返回类型的顶级 cv 限定与基类中返回类型的顶级 cv 限定不匹配,则派生类成员函数不会覆盖基类成员函数。

的返回类型中的类类型具有与 的返回类型中的类类型D::f相同或更少的 cv 限定B::f

这是指返回值的类类型的限定(即constin const int* volatile)。该规则意味着派生类成员函数中返回类型的限定必须等于或小于其覆盖的基类成员函数的返回类型限定。

于 2010-08-29T05:16:42.487 回答