Перегрузка оператора для оператора [] - PullRequest
2 голосов
/ 27 апреля 2010

Зачем вам перегружать оператор []? Я никогда не сталкивался с практическим сценарием, где это было необходимо. Может кто-нибудь сказать мне практический случай использования для этого.

Ответы [ 6 ]

8 голосов
/ 27 апреля 2010

Err .. std::vector<t>, std::basic_string<t>, std::map<k, v> и std::deque<t>?

Я использовал это для класса, представляющего раздел реестра, где operator[] возвращал объект, представляющий значение реестра со строкой между [] s.

См. Также Framework Parser Framework , который использует [] для семантических действий.

4 голосов
/ 27 апреля 2010

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

Вам не нужен этот синтаксис, если вы не занимаетесь общим программированием - он может выглядеть хорошо, но, если не считать косметики, вы всегда можете определить конкретные именованные методы такие как getAt, setAt и т. п., с аналогичными и более простыми для кода функциями.

Тем не менее, универсальное программирование лежит в основе современного C ++ ... и оно имеет жуткое сходство с "утилитарной типизацией во время компиляции" (я склонен к такой своеобразной терминологии, конечно, имея участие в его формировании - cfr wikipedia ; -).

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

3 голосов
/ 27 апреля 2010

Это полезно, если вы реализуете почти любой тип контейнера, который обеспечивает произвольный доступ (или, по крайней мере, некоторую форму доступа к ключу) к его элементам (например, рассмотрите std::vector).

1 голос
/ 27 апреля 2010

Хотя это и не является строго необходимым, это невероятно полезно для создания пользовательских контейнеров или строк, которые ведут себя как встроенные массивы или строки C. Это значительно сокращает многословие (например, в Java вы должны будете использовать x.getElementAt (i), в то время как в C ++ вы можете использовать x [i]; аналогично, в Java вам нужен x.compareTo (y) <0 в то время как в C ++ вы можете добиться того же, используя x <y). Это синтаксический сахар ... но это очень, очень вкусно. </p>

1 голос
/ 27 апреля 2010

Ну, несколько контейнеров STL дают несколько примеров - vector<> перегружает его, чтобы заставить его работать как массив. Например, map<> обеспечивает перегрузку operator[] для предоставления «ассоциативного массива».

1 голос
/ 27 апреля 2010

Если вы напишите класс, который наследуется от другого класса, который реализует оператор [], вы можете перезаписать оператор [], например std::vector или std::string. Если вы этого не сделаете, ваш класс может работать не так, как ожидает пользователь, так как ваш класс неявно унаследует реализацию родительского объекта [].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...