C++如何为封装vector<string>的类重载双层operator[]实现倒序字符访问
实现方案
该需求完全可以实现,核心实现思路是通过代理类(Proxy) 拦截第二层[]的访问逻辑,替换为你需要的倒序访问规则,同时保持原有的读写能力。
核心实现逻辑
- 不再让第一层
ReverseStringAccess::operator[]直接返回std::string&,而是返回一个自定义的代理类实例,该实例绑定对应下标的内部字符串的引用。 - 在代理类中重载
operator[],实现倒序下标的计算,直接返回对应字符的引用,即可同时支持读取和修改操作。
完整实现代码
#include <vector> #include <string> #include <stdexcept> class ReverseStringAccess { public: // 第二层[]的代理类,处理倒序访问逻辑 class StringProxy { public: explicit StringProxy(std::string& str) : target_str(str) {} // 重载[]实现倒序访问,返回字符引用支持修改 char& operator[](int j) { if (j < 0 || static_cast<size_t>(j) >= target_str.size()) { throw std::out_of_range("字符串下标越界"); } return target_str[target_str.size() - j - 1]; } // const版本重载,支持常量对象访问 const char& operator[](int j) const { if (j < 0 || static_cast<size_t>(j) >= target_str.size()) { throw std::out_of_range("字符串下标越界"); } return target_str[target_str.size() - j - 1]; } // 可选:类型转换运算符,支持直接获取完整字符串 operator std::string&() { return target_str; } operator const std::string&() const { return target_str; } private: std::string& target_str; }; ReverseStringAccess() = default; // 修正原构造函数语法错误,补充初始化列表的冒号 explicit ReverseStringAccess(std::vector<std::string> _arr) : arr(std::move(_arr)) {} // 第一层[]返回代理类实例 StringProxy operator[](int i) { if (i < 0 || static_cast<size_t>(i) >= arr.size()) { throw std::out_of_range("数组下标越界"); } return StringProxy(arr[i]); } // const版本的第一层[],支持常量对象访问 const StringProxy operator[](int i) const { if (i < 0 || static_cast<size_t>(i) >= arr.size()) { throw std::out_of_range("数组下标越界"); } return StringProxy(const_cast<std::string&>(arr[i])); } private: std::vector<std::string> arr; };
使用示例
#include <iostream> int main() { ReverseStringAccess obj({"hello", "world"}); // 倒序访问:obj[0][0]对应"hello"的最后一个字符'o' std::cout << obj[0][0] << std::endl; // 输出:o // 支持修改:修改倒序第0位,等价于修改原字符串最后一位 obj[0][0] = 'a'; // 输出修改后的完整字符串:halla std::cout << static_cast<std::string>(obj[0]) << std::endl; return 0; }
注意事项
- 代理类的生命周期和原
ReverseStringAccess对象绑定,不要脱离原对象单独保存代理类实例,避免出现悬垂引用。 - 如果不需要直接获取完整字符串,可以删掉代理类中的类型转换运算符,避免隐式转换带来的意料之外的行为,也可以替换为显式的
get()方法使用。 - 代码中补充的下标越界检查为可选实现,不需要可以直接删除。
内容的提问来源于stack exchange,提问作者Wais Kamal
相关产品推荐
相关产品推荐

