operator[]必须是非静态成员函数,因需隐式访问this指针;不支持友元重载;须声明于类内,推荐提供const与非const引用版本,参数宜用size_t以避免符号问题。
![c++怎么重载下标访问操作符[]](https://img.php.cn/upload/article/001/221/864/179281787184621.png?x-oss-process=image/resize,p_40)
operator[] 必须是类的非静态成员函数
因为 operator[] 需要隐式访问 this 指针来定位当前对象的数据,它不能是全局函数或静态成员。如果你在类外写 MyClass operator[](int i),编译器会直接报错:error: 'operator[]' must be a non-static member function。
常见错误是试图用友元实现,但 C++ 明确禁止——operator[] 不支持友元重载。
- 必须声明在类内部,例如:
int& operator[](size_t i); - 推荐同时提供 const 版本:
const int& operator[](size_t i) const;,否则const MyClass obj; obj[0]会编译失败 - 返回类型通常用引用(
T&或const T&),否则无法支持赋值操作,比如a[0] = 42
下标参数类型不强制是 int,但 size_t 更安全
你可以用 int、size_t、甚至自定义类型作参数,但实际中几乎都用 size_t。原因很实在:和 std::vector::size()、sizeof、new[] 等保持一致,避免有符号/无符号比较警告。
比如用 int i 当参数,而用户传入负数,你得自己检查;用 size_t i 虽然不能传负数(底层转成极大正数),但至少能统一边界判断逻辑。
- 别写
operator[](int i)然后只做i 判断——<code>i是负数时条件恒真,导致越界访问 - 如果真需要负索引(如环形缓冲),明确文档化,并在函数内做模运算,不要依赖参数类型“看起来像能负”
- 标准库容器(
vector、array)全用size_type,跟着它走最省心
返回引用还是值?取决于是否允许修改底层数据
返回 T& 支持左值使用(赋值、取地址),返回 T 只能读,且每次调用都触发拷贝——对大对象很伤性能。
但注意:如果内部存储是计算所得(比如稀疏矩阵的按需解压)、或做了缓存/代理,返回值可能更合适;不过这种场景已不属于典型下标语义,建议改用命名函数(如 at() 或 get())。
- 常规容器类:返回
T&和const T&两个重载 - 返回
void或bool是错的——破坏了[]的直觉行为 - 不要返回局部变量的引用,比如
return some_temp_value;,这是悬垂引用
operator[] 不做越界检查,at() 才该负责这个
operator[] 在 std::vector 和 std::array 中都不检查越界,这是有意设计:追求零开销抽象。你自己重载时也应保持这一契约——检查逻辑交给单独的 at() 成员函数。
混用两者容易出问题:有人以为 [] 安全,结果在 Release 模式下崩溃;或者过度检查拖慢高频访问路径。
-
operator[]:信任调用者,快速返回引用 -
at(size_t i):手动抛std::out_of_range,适合调试或不确定索引来源时 - 如果类本身不允许越界(如固定大小栈),可在
operator[]里断言:assert(i ,但别抛异常——这违背惯例
operator[] 的核心就三点:必须是成员函数、参数用 size_t 最稳妥、返回引用才符合下标操作的原始语义。最容易被忽略的是 const 版本缺失和越界检查错放到 [] 里——这两个点一旦出错,轻则编译失败,重则静默内存错误。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











