Перегрузка оператора [] - PullRequest
3 голосов
/ 30 марта 2011

Какие сценарии могут потребоваться для перегрузки оператора индекса?

И при чем тут функция assert? Я вижу, что в большинстве случаев использования assert для перегрузки нижнего индекса потребовалось бы пояснение.

Ответы [ 6 ]

7 голосов
/ 30 марта 2011

Вы можете перегрузить оператор [] в пользовательском контейнере, чтобы обеспечить синтаксически / семантически более понятный способ доступа к элементам.

Например, my_container[3] = 9; несколько яснее, чем my_container.set(3, 9);

Конечно, вы можете перегрузить [], чтобы сделать что-нибудь по существу, но, вероятно, не стоит.Например, вы можете заставить my_object[3] увеличивать my_object на 3, но семантически оператор [] передает поиск по индексу, и всегда лучше, чтобы ваши интерфейсы соответствовали ожиданиям.

Вы можете использовать assert для быстрой и грязной проверки границ;это приведет к беспорядочной смерти вашей программы, что всегда предпочтительнее, чем незначительное повреждение памяти.Преимущество заключается в том, что assert - это макрос, который может быть скомпилирован из производственного кода. Это означает, что вы можете оплатить накладные расходы, связанные с проверкой границ вашего контейнера в процессе разработки, а не в производстве, без изменения вашего кода.

3 голосов
/ 30 марта 2011

Вы могли бы рассмотреть перегрузку operator[] для классов, где операция (индекс (по одному полю имеет смысл), так как это имеет место для векторов (индекс по позиции) или сопоставления (индекс по ключу). Обратите внимание, что если естьэто более чем одно измерение для индексации, возможно, имеет смысл использовать другой оператор (operator()), так как operator[] принимает один аргумент. Вероятно, вы должны прочитать облегченную запись C ++ в OperatorПерегрузка .

В общем случае assert не имеет отношения к operator[] (или любому другому оператору). assert - это способ определения во время выполнения, что некоторые предварительные условия для операции выполняются, и должениспользовать для быстрого отказа и полного отказа когда вы обнаружите, что некоторые из ваших инвариантов сломаны.

1 голос
/ 30 марта 2011

Вы можете перегрузить operator[], если реализуете класс, являющийся коллекцией, или оболочкой для коллекции. Для меня я бы перегружал operator[] только в том случае, если операция могла быть выполнена в постоянное или почти постоянное время, поскольку именно так выполняется индексация массива. Возможно, имеет смысл использовать его для поиска значений в хеш-таблице, но не для индексации в связанный список.

Если вы обнаружите, что asserts используется в реализациях operator[], это может привести к тому, что аргумент индекса находится в пределах диапазона коллекций. Это, IMO, является неправильным использованием assert, так как assert должен использоваться для обнаружения внутренних ошибок программирования, а не для того, чтобы программа вызывалась неправильно. Конечное пользовательское или клиентское приложение никогда не должно видеть ошибку подтверждения. Другая возможность состоит в том, что этот класс используется только для внутреннего использования, и в этом случае ошибка утверждения выявила бы внутреннюю ошибку программирования, а не неверный аргумент, переданный клиентом.

1 голос
/ 30 марта 2011

Assert абсолютно не имеет ничего общего с оператором индексации operator[] per se .

Assert используется для проверки предварительных условий / инвариантов в отладочных сборках, поэтому их нарушения фиксируются перед началом работы.

Операторы индексирования подвержены типу ситуаций index out of range, который может объяснить, почему вы, кажется, замечаете их там чаще, чем где-либо еще. Я использую assert в основном, по крайней мере, один раз в каждой параметризованной функции и несколько раз на класс (проверка инвариантов).

НТН

1 голос
/ 30 марта 2011

Ну, с моими ограниченными знаниями об этом, я могу сказать, в ситуациях, когда классы содержат последовательность элементов. Вектор / Строка например. Для утверждения вы можете проверить этот сайт. - LINK -

0 голосов
/ 30 марта 2011

Возможно, вы захотите изменить диапазон вашего индекса (например, индексирование с 1 вместо 0) или представить многомерный массив одномерным массивом?

...