C++拆分.h与.cpp文件时关键字使用要求及顺序规则问询
头文件与.cpp文件的关键字使用规则
必须在.cpp实现中保留的关键字
const(成员函数的const限定):如果头文件里声明了带const的成员函数,比如int Class::bar() const;,cpp实现必须也加const,不然会被编译器当成另一个重载函数,直接编译报错。noexcept:头文件声明里带noexcept的函数,cpp实现必须匹配这个异常说明符,否则会触发未定义行为(除非是noexcept(false),虽然编译器可能允许省略,但建议严格保持一致)。constexpr:只要头文件声明了constexpr函数,cpp实现必须同样加上constexpr——毕竟constexpr要求函数能在编译期计算,实现部分必须明确这个属性才能满足标准要求。
绝对不能放到.cpp文件里的关键字
virtual:virtual只需要在第一次声明(一般是基类头文件)里加,派生类头文件的重写声明都可以不用,cpp实现里绝对不能加,加了不仅冗余,还不符合编码规范。override:override是用来检查是否正确重写基类虚函数的“声明期关键字”,只作用于头文件的函数声明,cpp实现里加了会直接编译报错。
函数声明的关键字顺序规则
你给出的virtual constexpr int foo() const override noexcept;,在C++14及以后的标准下是语法合法的,但需要遵循明确的顺序规则:
强制顺序要求(从左到右)
- 虚函数说明符(
virtual):仅用于基类的虚函数声明,可放在constexpr之前或之后,惯例上优先放在最前面。 - 常量表达式说明符(
constexpr):必须在返回类型之前,和virtual的顺序可互换,但通常放在virtual之后更清晰。 - 返回类型:比如
int,必须紧跟在修饰符之后、函数名之前。 - 函数名与参数列表:
foo(),是函数的核心标识部分。 - 成员函数cv限定符(
const/volatile):用来限制成员函数对类成员的修改权限,必须放在参数列表之后、重写说明符之前。 - 重写说明符(
override/final):用于验证虚函数重写的正确性,必须放在cv限定符之后、异常说明符之前。 - 异常说明符(
noexcept):指定函数是否允许抛出异常,必须放在所有声明修饰符的最后。
额外注意
- C11标准不允许
constexpr和virtual同时使用,只有C14及以后才支持constexpr虚函数,所以如果用C++11编译这个声明会直接报错。 override只能用于派生类的虚函数声明,基类的虚函数声明不需要加这个关键字。
内容的提问来源于stack exchange,提问作者gcc
相关产品推荐
相关产品推荐

