C++ std::string中at()方法与下标运算符[]的区别是什么?
std::string的
at()方法与下标运算符[]的差异对比 核心行为差异
- 越界处理逻辑不同
- 下标运算符
[]不会做下标越界检查:如果传入的下标超出了字符串的合法范围(>= str.size()或者小于0),属于未定义行为,程序可能直接崩溃,也可能读到脏数据、甚至出现安全漏洞,完全取决于运行环境和编译器实现。 at()方法会做严格的下标越界检查:如果下标非法,会直接抛出std::out_of_range异常,你可以通过异常捕获逻辑做容错处理,不会出现不可控的未定义行为。
- 下标运算符
- 性能表现不同
[]没有检查逻辑,运行效率更高,在性能敏感的高频调用场景下开销可以忽略。at()需要额外执行下标合法性判断,性能略低,不过绝大多数业务场景下这个开销可以忽略不计,只有极端高频的访问场景下才会有感知。
- 适用场景不同
- 如果你已经100%确定下标一定是合法的(比如下标是从0遍历到
str.size()-1的循环变量),直接用[]更简洁高效。 - 如果你拿到的下标是来自用户输入、外部接口返回等不可信来源,没法保证合法性的前提下,用
at()更安全,出问题也更容易排查。
- 如果你已经100%确定下标一定是合法的(比如下标是从0遍历到
示例代码
#include <iostream> #include <string> #include <stdexcept> int main() { std::string str = "test"; // 下标合法的情况,两者效果一致 std::cout << str[3] << std::endl; // 输出 't' std::cout << str.at(3) << std::endl; // 输出 't' // 下标越界的情况 // std::cout << str[5] << std::endl; // 未定义行为,可能输出乱码、可能崩溃 try { std::cout << str.at(5) << std::endl; } catch (const std::out_of_range& e) { std::cout << "访问越界: " << e.what() << std::endl; // 可以稳定捕获错误 } return 0; }
两种方式的优缺点总结
[]下标运算符
- 优点:
- 写法更简洁,符合常规的数组访问习惯
- 无额外检查开销,性能更高
- 缺点:
- 越界访问是未定义行为,排查问题难度高,有安全隐患
at()方法
- 优点:
- 越界访问有明确的异常抛出,错误逻辑可控,便于排查问题
- 对不可信输入的容错性更高,适合业务逻辑层使用
- 缺点:
- 写法相对繁琐
- 有极微的性能开销
- 需要处理异常,否则异常未捕获会直接终止程序
内容的提问来源于stack exchange,提问作者Nitin Shaily
相关产品推荐
相关产品推荐

