题目
编写程序,手写一个安全整型定长容器类 SafeArray。演示下标运算符 operator[] 的工业级双重载规范:必须成对提供非 const 版本 int& operator[](size_t index)(返回引用以支持作为左值被赋值修改)与 const 版本 const int& operator[](size_t index) const(保证常量对象只读访问);并通过越界防御断言或抛出 std::out_of_range 异常确保内存安全性。
输入格式:无需外部输入。
输出格式:输出非 const 对象的就地赋值与 const 对象的安全只读访问日志。
数据范围与约定:下标运算符双版本重载、常量正确性(const correctness)。
思路与算法
1. 为什么必须成对重载
若只提供非 const 版本,当一个函数接收了 const SafeArray& arr 时,尝试 arr[0] 会直接遭遇编译报错;若只提供按值返回或 const 引用的版本,外部代码将无法执行 arr[0] = 100。因此必须根据常量性严格双重载。
2. 引用返回的重要性
左值版本必须返回真正的引用 T&,唯有返回引用,调用点才能被当作可寻址的左值接收赋值表达式。
3. 边界安全检查
原生 C 数组下标越界属于静默未定义行为;重载的下标运算符可在开发阶段植入越界断言检测,极大提升代码健壮性。
完整程序
#include <iostream>
#include <stdexcept>
class SafeArray {
private:
int data_[5];
size_t size_{5};
public:
SafeArray() {
for (size_t i = 0; i < size_; ++i) data_[i] = (i + 1) * 10;
}
// 1. 非常量版本:返回左值引用,允许读取与修改写入
int& operator[](size_t index) {
if (index >= size_) {
throw std::out_of_range("非 const operator[] 访问下标越界!");
}
return data_[index];
}
// 2. 常量版本:返回 const 引用,只读保护
const int& operator[](size_t index) const {
if (index >= size_) {
throw std::out_of_range("const operator[] 只读访问下标越界!");
}
return data_[index];
}
size_t size() const { return size_; }
};
// 接收常引用的只读展示函数
void printConstArray(const SafeArray& arr) {
std::cout << "[只读函数] 遍历 const SafeArray: ";
for (size_t i = 0; i < arr.size(); ++i) {
std::cout << arr[i] << " "; // 自动命中 const operator[] 重载
}
std::cout << "\n";
}
int main() {
SafeArray mutableArr;
std::cout << "--- 1. 非 const 对象读写修改测试 ---\n";
std::cout << "修改前 mutableArr[0] = " << mutableArr[0] << "\n";
mutableArr[0] = 999; // 作为左值被修改
mutableArr[4] = 888;
std::cout << "修改后 mutableArr[0] = " << mutableArr[0] << "\n\n";
std::cout << "--- 2. 常量对象只读调用测试 ---\n";
const SafeArray constArr;
printConstArray(constArr);
std::cout << "\n--- 3. 越界异常拦截测试 ---\n";
try {
mutableArr[10] = 50; // 越界
} catch (const std::out_of_range& e) {
std::cout << "【安全防御】成功捕获越界异常: " << e.what() << "\n";
}
return 0;
}运行示例
输出:
--- 1. 非 const 对象读写修改测试 ---
修改前 mutableArr[0] = 10
修改后 mutableArr[0] = 999
--- 2. 常量对象只读调用测试 ---
[只读函数] 遍历 const SafeArray: 10 20 30 40 50
--- 3. 越界异常拦截测试 ---
【安全防御】成功捕获越界异常: 非 const operator[] 访问下标越界!