如何阻止自定义SortedArrayList通过继承的operator[]进行值赋值?
阻止SortedArrayList通过
operator[]赋值的几种方案 既然你的SortedArrayList<T>是靠排序规则维护元素有序性的,直接通过operator[]赋值会彻底破坏这种有序性,所以我们需要针对性禁用掉非const版本的operator[](也就是返回T&、允许修改元素的那个重载)。下面是几种实用的实现方式:
方案1:C++11及以后用= delete直接删除(最推荐)
这是最清晰、最直接的方式,编译器会直接拒绝任何调用非constoperator[]的代码:
template <typename T> class SortedArrayList : public ArrayList<T> { public: // 保留基类的const版本operator[],它仅用于读取元素,不会破坏有序性 using ArrayList<T>::operator[]; // 明确删除非const版本的operator[],禁止外部通过它赋值 T& operator[](const int& index) override = delete; // 你的SortedArrayList其他成员函数(比如自定义的add、remove等)... };
如果有人尝试写sortedList[0] = someValue;,编译器会直接报错,提示该函数已被删除,从根源上阻止了错误操作。
方案2:将非const operator[]设为私有(兼容旧C++标准)
如果你的项目需要兼容C++11之前的版本,可以把非const版本的operator[]声明为私有,并且不提供实现:
template <typename T> class SortedArrayList : public ArrayList<T> { private: // 重写基类的非const operator[],设为私有 T& operator[](const int& index) override; public: // 公开基类的const版本operator[] using ArrayList<T>::operator[]; // 你的SortedArrayList其他成员函数... };
这样外部代码调用非constoperator[]时会因为权限问题编译失败;如果类内部不小心调用了,链接阶段会因为找不到实现报错。
方案3:运行时抛出异常或编译断言(可选但不推荐)
如果你想在错误发生时给出明确提示,也可以采用这种方式,但不如前两种方案直接:
运行时抛出异常
template <typename T> class SortedArrayList : public ArrayList<T> { public: using ArrayList<T>::operator[]; T& operator[](const int& index) override { throw std::logic_error("禁止通过operator[]修改SortedArrayList,请使用add/remove等有序操作方法"); } // 你的SortedArrayList其他成员函数... };
编译时触发断言
template <typename T> class SortedArrayList : public ArrayList<T> { public: using ArrayList<T>::operator[]; T& operator[](const int& index) override { static_assert(false, "禁止通过operator[]修改SortedArrayList,请使用add/remove等有序操作方法"); return ArrayList<T>::operator[](index); // 仅为编译通过,永远不会执行到 } // 你的SortedArrayList其他成员函数... };
这种方案要么到运行时才报错,要么依赖C++11的static_assert,代码也有冗余,所以优先级低于前两种。
补充提示
- 一定要保留const版本的
operator[],它用于安全读取元素,不会破坏有序性,用户仍然可以通过const SortedArrayList<T>&来下标访问元素。 - 建议在类的注释里明确说明禁用非const
operator[]的原因,引导用户使用符合排序逻辑的add、remove等方法修改容器。
内容的提问来源于stack exchange,提问作者t4dohx
相关产品推荐
相关产品推荐

