重写方法时非POD类型const指针无编译器警告问题咨询
派生类重写虚函数:POD与非POD指针的const限定差异原因
这背后的核心是C++标准对协变返回类型的规则区分,针对类类型和内置POD类型有不同的处理逻辑:
1. 内置POD类型的情况(如int)
当基类虚函数返回const int*,派生类试图用int*重写时,编译器报错的原因是:
- C++的协变返回类型规则仅适用于指向类类型的指针/引用,内置POD类型(如int)不属于类类型,因此无法触发协变规则。
- 此时派生类的返回类型
int*与基类的const int*既不完全一致,也不符合协变要求(因为const int和int是无继承关系的不同类型),所以编译器判定为非法的重写,抛出「invalid covariant return type」警告。
示例代码:
struct B1 { virtual const int* f(); }; struct D1 : B1 { int* f() override; // 编译器报错:非法协变返回类型 };
2. 非POD类/结构体类型的情况
当基类虚函数返回const S*(S是自定义结构体),派生类用S*重写时,编译器允许的原因是:
- 针对类类型的指针返回值,C++标准允许协变返回类型放宽cv限定符:只要派生类返回的指针指向基类返回类型所指向的类(或其派生类),且派生类的cv限定符(这里是无const)不超过基类的cv限定符(这里是const),就属于合法的重写。
S*可以隐式转换为const S*,且S是类类型,完全符合协变规则的要求,因此编译器不会触发警告。
示例代码:
struct S { }; struct B2 { virtual const S* f(); }; struct D2 : B2 { S* f() override; // 合法,符合协变规则 };
简单来说:类类型的const/非const指针属于同一类型体系的限定变体,允许通过协变规则放宽const;而内置POD类型的const/非const指针是无继承关系的独立类型,无法适用协变规则,因此重写时会报错。
内容的提问来源于stack exchange,提问作者arapEST
相关产品推荐
相关产品推荐

