Итератор C++ против объекта с методом length()

Мой вопрос относится к примеру из Maya C++ API, и я интересно, относится ли это к Maya или к общей идиоме C++

В API Maya есть объект с именем MSelectionList, который представляет собой контейнер, представляющий объекты на сцене. У него также есть компаньон MItSelectionList, который является итератором для экземпляра MSelectionList.

Теперь я понимаю, что преимущество итератора заключается в том, что он знает, как правильно перебирать объект, но в этом случае MSelectionList имеет метод .length(), а также те же геттеры, что и итератор, за исключением того, что вы предоставляете индекс.

Пример...

MSelectionList

MSelectionList activeList;
MGlobal::activeSelectionList(activeList);

unsigned int length = activeList.length();
for (unsigned int i=0 ; i < length; i++ ) {
    MDagPath item;
    iter.getDagPath(i, item);
}

MItSelectionList

MSelectionList activeList;
MGlobal::activeSelectionList(activeList);
MItSelectionList iter( activeList );

for ( ; !iter.isDone(); iter.next() ) {
    MDagPath item;
    iter.getDagPath(item);
}

Единственное, что итератор предоставляет по сравнению с обычным объектом выбора, — это возможность установить тип фильтра, чтобы он возвращал только объекты, соответствующие фильтру. Хотя вы могли бы выполнить этот же тест явно в первом примере.

Мой вопрос заключается в том, в чем польза итератора, когда функциональность итератора и исходного объекта пересекается, как это? Является ли это просто дизайнерским решением, специфичным для Maya, или это общая идиома С++, чтобы всегда создавать итераторы по какой-то дополнительной причине, которую я здесь не понимаю.


person jdi    schedule 09.08.2012    source источник


Ответы (1)


Я не знаком с Maya, но я считаю, что этот вопрос связан с аргументом между итераторами и индексацией.

Согласно статье в Википедии об итераторах, итераторы имеют следующие преимущества:

  • Циклы подсчета подходят не для всех структур данных, в частности для структур данных без произвольного доступа или с медленным доступом, таких как списки или деревья.
  • Итераторы могут обеспечить согласованный способ повторения структур данных всех типов и, следовательно, сделать код более читабельным, пригодным для повторного использования и менее чувствительным к изменениям в структуре данных.
  • Итератор может налагать дополнительные ограничения на доступ, например гарантировать, что элементы нельзя пропустить или что ранее посещенный элемент не может быть доступен во второй раз.
  • Итератор может разрешить изменение объекта-контейнера, не делая итератор недействительным. Например, когда итератор продвинулся дальше первого элемента, можно будет вставить дополнительные элементы в начало контейнера с предсказуемыми результатами. При индексации это проблематично, так как номера индексов должны измениться.

Для вашего конкретного примера похоже, что третий маркер наиболее применим, потому что MItSelectionList предоставляет только функцию-член next() для обеспечения того, чтобы элементы не пропускались (если не применяется фильтр).

person Jesse Good    schedule 09.08.2012
comment
Спасибо за информацию. Вы бы поставили на то, что это в основном удобство в случае этого конкретного набора классов? Потому что, как я и предполагал, я мог бы применить ту же операцию фильтра вручную, проверив типы, но для меня это явно больше кода. Мне не совсем понятна польза от next защиты от пагубного пропуска элементов. - person jdi; 09.08.2012
comment
@jdi: Возможно, удобство и читабельность являются частью этого, но я бы сказал, что он также обеспечивает более строгий набор правил и предотвращает больше ошибок (хотя для тривиального примера это может быть неочевидно). - person Jesse Good; 09.08.2012