[Этот пример] написан в понятном объектно-ориентированном стиле с использованием методов получения и установки. Сторонники этого стиля говорят, что преимущество таких функций состоит в том, что они позволяют программистам впоследствии изменять реализацию. То, что они забывают упомянуть, так это то, что иногда ужасно хорошо разоблачать реализацию. Давайте посмотрим, что я имею в виду. Мне трудно представить эволюцию системы, которая позволила бы вам сохранить интерфейс получения и установки, но иметь возможность изменить реализацию. Я мог бы представить, что реализация перерастает int
и вам нужно переключиться на long
. Но это другой интерфейс. Я могу себе представить, что вы решили переключиться с массива на список, но это также заставит вас изменить интерфейс, поскольку на самом деле не очень хорошая идея индексировать в связанный список.
Теперь давайте посмотрим, почему действительно полезно выставлять реализацию. Давайте предположим, что завтра вы решите отсортировать целые числа. Как ты можешь это сделать? Не могли бы вы использовать библиотеку C
qsort
? Нет, так как он ничего не знает о ваших геттерах и сеттерах. Не могли бы вы использовать STL sort
? Ответ тот же. Хотя вы разрабатываете свой класс, чтобы выдержать некоторые гипотетические изменения в реализации, вы не разработали его для очень распространенной задачи сортировки. Конечно, сторонники методов получения и установки предложат вам расширить свой интерфейс с помощью функции-члена sort
. После этого вы обнаружите, что вам нужен бинарный поиск, медиана и т. Д. Очень скоро ваш класс будет иметь 30 функций-членов, но, конечно, он будет скрывать реализацию. И это может быть сделано, только если вы являетесь владельцем класса. В противном случае вам необходимо реализовать достойный алгоритм сортировки поверх интерфейса «сеттер-получатель» с нуля, и это гораздо более сложное и опасное действие, чем можно себе представить. ...
Сеттеры и геттеры усложняют наше ежедневное программирование, но обещают огромные выгоды в будущем, когда мы обнаружим лучшие способы хранения массивов целых чисел в памяти. Но я не знаю ни одного реалистичного сценария, когда сокрытие областей памяти внутри нашей структуры данных помогает, а воздействие наносит ущерб; поэтому я обязан предоставить гораздо более удобный интерфейс, который также соответствует привычному интерфейсу массивов C
. Когда мы программируем в C++
, нам не должно быть стыдно за его C
наследие, но в полной мере использовать его. Единственные проблемы с C++
и даже единственные проблемы с C
возникают, когда они сами не согласуются с их собственной логикой. ...
Мое замечание по поводу раскрытия местоположений адресов последовательных целых чисел не является остроумным.
Потребовалось много усилий, чтобы убедить комитет по стандартизации, что такое требование
существенное свойство векторов; однако они не согласны с тем, что итераторы вектора должны
указатели и, следовательно, на нескольких основных платформах - в том числе Microsoft - это
быстрее отсортировать ваш вектор, сказав невероятно уродливый
if (!v.empty()) {
sort(&*v.begin(), &*v.begin() + v.size());
}
, чем предполагалось
sort(v.begin(), v.end());
Попытки навязать псевдо-абстрактность ценой эффективности могут быть побеждены, но за ужасную цену.
Да, есть несколько правил, касающихся ООП. Нет, я не уверен, что это действительно лучший способ сделать что-то. Когда вы работаете с STL, имеет смысл делать вещи, совместимые с STL. А когда ваша абстракция имеет низкий уровень (например, std::vector
, что предназначено специально для упрощения работы с динамически размещаемыми массивами; т. Е. Она должна использоваться почти как массив с некоторыми дополнительными функциями), тогда некоторые из этих правил ООП будут полезны не имеет никакого смысла вообще.
Чтобы ответить на первоначальный вопрос: даже новичкам в конечном итоге нужно будет узнать об итераторах, времени жизни объекта и о том, что я назову сроком полезного использования объекта (т. Е. «Объект не выпал из области видимости, но больше не действителен»). использовать, как недействительный итератор "). Я не вижу смысла пытаться скрыть эти факты жизни от пользователя, поэтому лично я бы не стал исключать API на основе итераторов на этих основаниях. Реальный вопрос заключается в том, что ваш API предназначен для абстрагирования и что он должен представлять (аналогично тому факту, что vector
является более хорошим массивом и предназначен для раскрытия его природы массива). Если вы ответите на это, у вас должно получиться лучшее представление о том, имеет ли смысл API на основе итераторов.