函数后面的const与noexcept
C++ 中函数后面的 const
和 noexcept
的含义
在 C++ 中,函数声明或定义后添加的 const
和 noexcept
是函数修饰符,用于指定函数的行为和属性。
1. 函数后面的 const
含义
- 成员函数限定符:
const
出现在类成员函数的声明或定义后,表示该函数不会修改对象的非mutable
成员变量。 - 承诺:调用该函数时,对象的状态(除
mutable
成员外)保持不变。 - 语义:用于声明“只读”成员函数,增强代码安全性。
实现机制
- 编译器将
const
成员函数的this
指针视为const T*
(而非T*
),禁止修改非mutable
成员。 - 可被
const
对象、引用或指针调用,而非const
成员函数只能被非const
对象调用。
代码示例
1 |
|
应用场景
- 只读访问:用于访问对象状态而不修改(如 getter 函数)。
- const 正确性:确保
const
对象或引用能安全调用函数。 - 接口设计:提高类接口的语义清晰性和安全性。
注意事项
mutable
成员可在const
函数中修改,需谨慎使用。- 重载时,
const
和非const
版本可共存,编译器根据调用对象的const
属性选择。
2. 函数后面的 noexcept
含义
- 异常规范:
noexcept
表示函数承诺不抛出异常(或有条件不抛出)。 - 性能优化:编译器可优化不抛异常的函数(如减少异常处理开销)。
- C++11 引入:位于
<exception>
,用于增强异常安全性和性能。
实现机制
noexcept
分为两种:- **无条件
noexcept
**:noexcept
或noexcept(true)
,保证不抛异常。 - **条件
noexcept
**:noexcept(expression)
,根据表达式决定是否抛异常。
- **无条件
- 若
noexcept
函数抛出异常,程序调用std::terminate()
终止。
代码示例
1 |
|
应用场景
- 性能优化:在标准库容器(如
std::vector
)的移动操作中,noexcept
函数可启用更高效的实现(强异常保证)。 - 异常安全性:明确函数的异常行为,方便调用者处理。
- 模板编程:配合
noexcept
运算符(如std::is_nothrow_move_constructible
)优化代码。
注意事项
- 错误使用
noexcept
(抛出异常)会导致程序终止,需确保函数逻辑符合承诺。 - 使用
noexcept
运算符检查函数是否为noexcept
:1
static_assert(noexcept(func1()), "func1 should be noexcept");
3. 结合使用 const
和 noexcept
const
和noexcept
可同时用于成员函数,互不冲突。- 语法:
ReturnType func() const noexcept;
- 示例:
1
2
3
4
5class MyClass {
int x;
public:
int getX() const noexcept { return x; } // 只读且不抛异常
};
应用场景
- 高性能只读函数:如标准库中的访问器函数,需高效且安全。
- 严格接口:在要求高可靠性的系统中,明确函数行为。
4. 对比总结
特性 | const |
noexcept |
---|---|---|
作用 | 禁止修改对象状态 | 承诺不抛异常 |
适用范围 | 成员函数 | 任何函数(成员或非成员) |
编译器行为 | 限制 this 为 const |
优化代码,异常抛出调用 terminate |
性能影响 | 无直接影响 | 减少异常处理开销 |
语义 | 保证状态不变 | 保证异常安全 |
5. 注意事项
- 误用后果:
const
函数修改非mutable
成员会导致编译错误。noexcept
函数抛出异常会导致程序终止。
- 与智能指针结合(结合上下文):
- 智能指针(如
unique_ptr
、shared_ptr
)的析构函数通常是noexcept
,确保异常安全。 - 成员函数操作智能指针时,
const
保证不修改指针状态,noexcept
优化析构或移动操作。
- 智能指针(如
- C++ 标准演进:
- C++11 引入
noexcept
和alignof
,C++17 增强noexcept
推导。 - 优先使用
std::make_unique
/make_shared
(如上下文所述),它们通常是noexcept
的。
- C++11 引入
6. 总结
- **
const
**:用于成员函数,保证不修改对象状态,适合只读操作。 - **
noexcept
**:承诺函数不抛异常,提升性能和异常安全性,适合移动操作或关键路径。 - 结合使用:在高性能、强安全场景中,
const noexcept
提供清晰语义和优化。
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Comments