- Почему вы вообще передаете индекс в качестве ссылки? Абсолютно не нужно ...
- Я лично рекомендую использовать целочисленные типы без знака для индексов массива (что в любом случае будет означать отрицательный индекс ???).
- const для типа, возвращаемого значением, является (почти) бессмысленным - он все равно будет скопирован в другую переменную (которая тогда будет изменяемой), но вы предотвратите семантику перемещения ...
Итак:
T& operator[](unsigned int index); //get reference (LHS)
T operator[](unsigned int index) const; //get copy (RHS)
(Только некоторые предложения по улучшению ...)
Теперь к актуальному вопросу: запретить модификацию довольно просто:
//T& operator[](unsigned int index); //get reference (LHS)
T const& operator[](unsigned int index) const; //get copy (RHS)
Всего один оператор индекса, всегда возвращающий константную ссылку ... Если пользователь может жить со ссылкой, хорошо, иначе он / она все равно скопирует значение ...
Изменить в адаптации к измененному вопросу:
Поскольку теперь происходит наследование, все усложняется. Вы не можете просто избавиться от некоторой унаследованной функции, а унаследованная будет разрешать изменение элемента.
В данной ситуации я бы рассмотрел редизайн (если это возможно):
class ArrayListBase
{
public:
T const& operator[](unsigned int index) const;
// either copy or const reference, whichever appears more appropriate to you...
};
class ArrayList : public ArrayListBase
{
public:
using ArrayListBase::operator[];
T& operator[](unsigned int index);
}
class SortedArrayList : public ArrayListBase
{
public:
// well, simply does not add an overload...
}
Функции вставки могут быть чисто виртуальными в базовом классе (где подходит общий интерфейс) или доступны только в производных классах. Решай ты ...