34、在 deque中使用 [] 操作符和 at() 方法有何区别?
一、核心区别
-
边界检查机制
operator[]
:不进行越界检查,访问越界时导致未定义行为(如程序崩溃、数据损坏)at()
:进行严格越界检查,越界时抛出std::out_of_range
异常
-
性能差异
operator[]
:无额外检查,时间复杂度为 O ( 1 ) O(1) O(1),适合高频访问且索引可控的场景at()
:每次访问需验证索引,轻微性能损耗,适合需要安全校验的场景
二、用法对比
特性 | operator[] | at() |
---|---|---|
语法示例 | dq[3] = 5; | dq.at(3) = 5; |
异常处理 | 需手动检查索引 | 自动抛出异常 |
性能优化场景 | 高频循环遍历 | 不确定索引的访问 |
三、代码示例
#include <deque>
#include <iostream>
#include <stdexcept>
int main() {
std::deque<int> dq{10, 20, 30};
// 1. operator[] 用法
dq[1] = 200; // 直接修改第二个元素
std::cout << "dq[2] = " << dq[2] << std::endl; // 安全索引
// 2. at() 用法
try {
dq.at(3) = 400; // 越界访问会抛出异常
} catch (const std::out_of_range& e) {
std::cerr << "Error: " << e.what() << std::endl; // 捕获异常
}
return 0;
}
四、选择建议
- 优先使用
operator[]
:在已知索引安全时(如循环遍历) - 必须使用
at()
:当索引可能来自不可靠输入(如用户输入或动态计算值)
五、底层原理补充
deque通过_Map_pointer
管理分段存储的缓冲区,operator[]
和at()
均通过计算块地址和偏移量实现
O
(
1
)
O(1)
O(1)访问。两者的核心差异仅体现在是否调用_M_range_check
函数进行边界验证。