跳转到内容

C++ 下标运算符重载

来自代码酷

C++下标运算符重载[编辑 | 编辑源代码]

简介[编辑 | 编辑源代码]

下标运算符重载(Subscript Operator Overloading)是C++中一种允许用户自定义类对象使用数组式访问(即`[]`运算符)的技术。通过重载`operator[]`,开发者可以为自定义类提供类似原生数组的访问方式,增强代码的可读性和灵活性。下标运算符通常用于容器类(如动态数组、矩阵、字典等),使其支持直观的元素访问语法。

语法[编辑 | 编辑源代码]

下标运算符重载的函数原型有两种形式,分别对应非const和const对象:

// 非const版本(允许修改返回值)
T& operator[](int index);

// const版本(只读访问)
const T& operator[](int index) const;

其中`T`是元素类型,`index`是下标参数。

基本示例[编辑 | 编辑源代码]

以下是一个简单的动态数组类`IntArray`,演示如何重载下标运算符:

#include <iostream>
#include <vector>

class IntArray {
private:
    std::vector<int> data;
public:
    IntArray(std::initializer_list<int> init) : data(init) {}

    // 非const版本
    int& operator[](size_t index) {
        if (index >= data.size()) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    }

    // const版本
    const int& operator[](size_t index) const {
        if (index >= data.size()) {
            throw std::out_of_range("Index out of range");
        }
        return data[index];
    }

    size_t size() const { return data.size(); }
};

int main() {
    IntArray arr = {10, 20, 30, 40};

    // 修改元素(调用非const版本)
    arr[1] = 99;

    // 读取元素(可能调用const版本)
    for (size_t i = 0; i < arr.size(); ++i) {
        std::cout << arr[i] << " ";
    }
    // 输出:10 99 30 40
}

边界检查[编辑 | 编辑源代码]

良好的下标运算符实现应包含边界检查(如上例中的`if`语句),防止越界访问。C++标准库的`std::vector::operator[]`不进行边界检查,而`std::vector::at()`会抛出异常,开发者可根据需求选择风格。

多维访问[编辑 | 编辑源代码]

通过返回代理对象或使用多参数,可实现多维下标访问:

class Matrix {
private:
    std::vector<std::vector<int>> data;
public:
    Matrix(size_t rows, size_t cols) : data(rows, std::vector<int>(cols)) {}

    // 返回行代理
    std::vector<int>& operator[](size_t row) {
        return data[row];
    }

    // 多参数版本(C++23起支持)
    int& operator[](size_t row, size_t col) {
        return data[row][col];
    }
};

实际应用案例[编辑 | 编辑源代码]

案例:安全字符串类

class SafeString {
    char* buffer;
    size_t length;
public:
    SafeString(const char* str) : length(strlen(str)) {
        buffer = new char[length + 1];
        strcpy(buffer, str);
    }

    // 非const版本允许修改字符
    char& operator[](size_t index) {
        if (index >= length) throw std::out_of_range("Invalid index");
        return buffer[index];
    }

    // const版本用于只读访问
    const char& operator[](size_t index) const {
        if (index >= length) throw std::out_of_range("Invalid index");
        return buffer[index];
    }
};

注意事项[编辑 | 编辑源代码]

1. 返回值类型:通常返回引用以支持左值操作(如`obj[i] = x`) 2. const正确性:必须提供const版本以保证const对象可用 3. 异常安全:边界检查应抛出`std::out_of_range`等标准异常 4. 性能考量:频繁调用的场景可提供无检查版本(如`unsafe_at()`)

与其他运算符的关系[编辑 | 编辑源代码]

graph LR A[operator[]] --> B(容器类) A --> C(代理对象) C --> D[实现多维访问] A --> E[与operator=结合]

数学表示[编辑 | 编辑源代码]

对于类`C`的下标运算,可形式化表示为: C::operator[](i)vi其中0i<n

总结[编辑 | 编辑源代码]

下标运算符重载是C++实现类数组行为的核心工具,正确使用能大幅提升API的直观性。开发者需注意边界安全、const正确性和返回值设计,结合实际需求选择最合适的实现方案。