$ 10.3 / 5
“覆盖的返回类型 功能应与...相同 被覆盖的返回类型 函数或与类的协变 的功能。如果是函数D :: f 覆盖函数B :: f,返回 函数的类型是协变的 如果他们满足以下要求 标准:
- 两者都是指向 类或对类的引用98)
- 返回类型为B :: f的类 与班级中的班级相同 返回类型D :: f,或者是 直接或明确无误的 中的类的间接基类 D :: f
的返回类型- 指针或引用都有 相同的cv资格和 返回类型为D :: f的类类型 具有与或相同的cv资格 比班级更少的cv资格 输入B :: f的返回类型。
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只是想要变得更好。但在这种情况下,它是最令人困惑的。
答案 0 :(得分:2)
第5行和第9行的警告“返回类型的类型限定符无意义”是因为非类型的rvalues永远不会被cv限定。
由于按值返回的函数的结果是rvalue且指针是非类型类型,因此返回的指针不是cv限定的,即使返回类型表明它是。
此警告与协方差无关。以下函数会导致相同的警告:
int* volatile f() { return 0; }
至于10.3 / 5中引用的文字:
指针或引用都具有相同的cv-qualification
这是指返回类型的顶级限定条件(即volatile
中的const int* volatile
)。虽然顶级资格是没有意义的,但确实会影响函数的类型,因此,如果上面有f
的声明,则此代码段不正确:
int* (*q)() = f; // error: can't convert int* volatile (*)() to int* (*)()
同样,如果派生类成员函数中返回类型的顶级cv限定条件与基类中返回类型的顶级cv限定条件不匹配,则派生类成员函数不会覆盖基类成员函数。
返回类型
D::f
中的类类型与返回类型B::f
中的类类型具有相同的cv-qualification或更少的cv-qualification。
这是指返回值的类类型的限定(即const
中的const int* volatile
)。此规则意味着派生类成员函数中的返回类型的限定必须等于或小于它覆盖的基类成员函数的返回类型的限定。