类属性说明符 (自 C++26 起)
指定一个类是可替换的 (replaceable_if_eligible)、可平凡重定位的 (trivially_relocatable_if_eligible),或者一个类不能被继承 (final)。
目录 |
[编辑] 语法
类属性说明符 出现在类定义的开头,紧跟在类名之后,并且不能出现在类声明中。
class-key attr (可选) class-head-name class-prop-specifier-seq (可选) base-clause (可选) | |||||||||
class-prop-specifier-seq | - | 一个或多个 class-prop-specifier,但每个最多出现一次。 |
class-prop-specifier | - | 以下之一:final、replaceable_if_eligible 和 trivially_relocatable_if_eligible。 |
在 (C++26) 之前,class-virt-specifier (可选) 代替了 class-prop-specifier-seq (可选),它仅允许 final 用于 final
说明符 (自 C++11 起)。
[编辑] 解释
final、replaceable_if_eligible 和 trivially_relocatable_if_eligible 是在类头中使用时具有特殊含义的标识符。在其他上下文中,它不是保留字,可以用于命名对象和函数。
[编辑] final 说明符
final 指定此类不能出现在另一个类定义的 base-specifier-list 中(换句话说,不能被继承)。否则,程序是非良构的(会生成编译时错误)。final 也可以与 union 定义一起使用,在这种情况下它没有效果(除了对 std::is_final 的结果产生影响外)(自 C++14 起),因为 union 不能被继承。
[编辑] replaceable_if_eligible 说明符
replaceable_if_eligible 指定如果此类有资格被替换,则它是可替换的。
[编辑] trivially_relocatable_if_eligible 说明符
trivially_relocatable_if_eligible 指定如果此类有资格被平凡重定位,则它是平凡可重定位的。
[编辑] 可替换性
如果类 C
有资格被替换 并且满足以下任一条件,则它是可替换的:
[编辑] 可替换的资格
除非满足以下任一条件,否则类 C
是有资格被替换的:
- 它具有一个不是可替换的类的基类
- 它具有一个不是可替换的类型的非静态数据成员
- 当从类型为
C
的将亡值直接初始化类型为C
的对象时,重载解析失败或选择了已删除的构造函数 - 当从类型为
C
的将亡值赋值给类型为C
的左值时,重载解析失败或选择了已删除的赋值运算符函数 - 它具有已删除的析构函数。
[编辑] 平凡可重定位性
如果类有资格被平凡重定位 并且满足以下任一条件,则它是平凡可重定位的:
[编辑] 平凡重定位的资格
除非满足以下任一条件,否则类是有资格被平凡重定位的:
除非实现定义了是否具有一个或多个多态类类型子对象的其他符合条件的 union
是有资格被平凡重定位的。
[编辑] 默认可移动性
如果满足以下所有条件,则类 C
是默认可移动的:
- 从类型为
C
的将亡值直接初始化类型为C
的对象的重载解析选择了一个构造函数,该构造函数是C
的直接成员,既不是用户提供的也不是已删除的 - 从类型为
C
的将亡值赋值给类型为C
的左值的重载解析选择了一个赋值运算符函数,该函数是C
的直接成员,既不是用户提供的也不是已删除的 -
C
具有一个既不是用户提供的也不是已删除的析构函数。
[编辑] 关键字
final、replaceable_if_eligible、trivially_relocatable_if_eligible。
[编辑] 注意
- 并非所有 TriviallyCopyable 类都是可替换的或平凡可重定位的。
- 在建立平凡可重定位性或可替换性时,不考虑可访问性特殊成员函数。
- 具有 const 限定或引用非静态数据成员的类可以是平凡可重定位的。
- 没有用户声明的特殊成员函数的
union
和默认可移动的类都是可替换的和平凡可重定位的,即使在没有类属性说明符的情况下定义也是如此。
特性测试宏 | 值 | Std | 特性 |
---|---|---|---|
__cpp_trivial_relocatability |
202502L |
(C++26) | 平凡可重定位性 |
[编辑] 示例
struct final; // OK; declares a class named 'final', // does not use class property specifiers. struct IF final; // Ill-formed: class property specifiers // cannot appear at function declaration. struct F final {}; // OK; specifier marks class F as non-derivable. struct D: F {}; // Ill-formed: class F cannot be derived from. // OK; specifier marks class R as 𝘳𝘦𝘱𝘭𝘢𝘤𝘦𝘢𝘣𝘭𝘦 if eligible. struct R replaceable_if_eligible {}; // OK; specifier marks class T as 𝘵𝘳𝘪𝘷𝘪𝘢𝘭𝘭𝘺 𝘳𝘦𝘭𝘰𝘤𝘢𝘵𝘢𝘣𝘭𝘦 if eligible. struct T trivially_relocatable_if_eligible {}; // OK; a class can be marked with multiple class property specifiers. struct FRT final replaceable_if_eligible trivially_relocatable_if_eligible {}; // Ill-formed: each class property specifier can appear at most once. struct FRF final replaceable_if_eligible final {}; int main() {}
[编辑] 参考
- C++26 标准 (ISO/IEC 14882:2026)
- 6.8.1 平凡可重定位和可替换类型 [basic.types.general]
[编辑] 参见
final 说明符 (C++11) |
声明一个方法不能被重写或一个类不能被继承 |
(C++14) |
检查一个类型是否为 final 类类型 (类模板) |