77. Вместо массивов используйте vector и string
77. Вместо массивов используйте vector и string
Резюме
Избегайте реализации абстракция массива посредством массивов в стиле С, арифметики указателей и примитивов управления памятью. Использование vector или string не только сделает проще вашу жизнь, но и позволит написать более безопасную и масштабируемую программу.
Обсуждение
Сегодня едва ли не основными вопросами при написании программного обеспечения являются вопросы безопасности и переполнения буфера. Ограничения, связанные с фиксированным размером массивов, доставляют немало беспокойства, даже если приложению удается остаться в рамках корректности. Все эти проблемы связаны с использованием старых средств С, таких как встроенные массивы, указатели и их арифметика, а также управление памятью вручную вместо таких высокоуровневых концепций, как буферы, векторы и строки.
Вот некоторые из причин, по которым массивам в стиле С следует предпочесть стандартные средства С++.
• Они автоматически управляют собственной памятью. Больше не требуется никаких фиксированных буферов с размером "большим, чем любая разумная длина" ("бомба с часовым механизмом" — вот как правильно прочесть это определение), или сплошных перераспределений памяти при помощи reallос и соответствующих обновлений указателей.
• У них богатый интерфейс. Вы легко и выразительно можете реализовать сложную функциональность.
• Они совместимы с моделью памяти в С. vector и string::c_str могут быть переданы функциям API на языке С. В частности, в С++ vector служит "переходником" к С и другим языкам программирования (см. рекомендации 76 и 78).
• Они обеспечивают расширенные возможности проверки. Стандартные средства позволяют реализовать (в отладочном режиме) итераторы и операторы индексирования, которые способны выявить большой класс ошибок памяти. Многие из современных реализаций стандартной библиотеки предоставляют такие отладочные возможности — воспользуйтесь ими! (См. рекомендацию 83.)
• Они практически не снижают эффективность ваших программ. В классах vector и string при выборе между эффективностью и безопасностью решение принимается в пользу эффективности (естественно, не в отладочном режиме). Тем не менее, стандартные средства оказываются гораздо лучшей платформой для создания безопасных компонентов, чем обычные массивы и указатели.
• Они стимулируют оптимизацию. Современные реализации стандартной библиотеки включают оптимизации, о которых многие из нас просто никогда бы и не подумали.
Применение массива может быть оправданно, когда его размер фиксирован на стадии компиляции (например, float[3] для трехмерной точки; переход к четвертому измерению все равно потребует перепроектирования программы).
Ссылки
[Alexandrescu01а] • [Dewhurst03] §13, §60, §68 • [Meyers01] §13, §16 • [Stroustrup00] §3.5-7, §5.3, §20.4.1, §C.7 • [Sutter00] §36
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
76. По умолчанию используйте vector . В противном случае выбирайте контейнер, соответствующий задаче
76. По умолчанию используйте vector. В противном случае выбирайте контейнер, соответствующий задаче РезюмеОчень важно использовать "правильный контейнер". Если у вас есть весомые причины выбрать определенный тип контейнера, используйте тот контейнер, который наиболее
78. Используйте vector (и string::c_str ) для обмена данными с API на других языках
78. Используйте vector (и string::c_str) для обмена данными с API на других языках Резюмеvector и string::c_str служат шлюзом для сообщения с API на других языках. Однако не полагайтесь на то, что итераторы являются указателями; для получения адреса элемента, на который ссылается vector<T>::iterator
19.2.1.5. Используйте вместо формата по умолчанию (-е) форматы -с или -и
19.2.1.5. Используйте вместо формата по умолчанию (-е) форматы -с или -и Принятый по умолчанию в diff(1) формат -е является крайне ненадежным. Он не включает в себя контекст, поэтому утилита patch не может справиться со своей задачей, если какие-либо строки были вставлены в код
19.2.1.5. Используйте вместо формата по умолчанию (-e ) форматы -с или -u
19.2.1.5. Используйте вместо формата по умолчанию (-e) форматы -с или -u Принятый по умолчанию в diff(1) формат -е является крайне ненадежным. Он не включает в себя контекст, поэтому утилита patch не может справиться со своей задачей, если какие-либо строки были вставлены в код главной
6.2. Эффективное использование vector
6.2. Эффективное использование vector ПроблемаВы используете vector, и при этом имеются жесткие требования по объему или времени выполнения кода и требуется снизить или устранить все накладные расходы.РешениеПоймите, как реализован vector, узнайте о сложности методов вставки и
Совет 5. Используйте интервальные функции вместо одноэлементных
Совет 5. Используйте интервальные функции вместо одноэлементных Есть два вектора, v1 и v2. Как проще всего заполнить v1 содержимым второй половины v2? Только не надо мучительно размышлять над тем, что считать «половиной» при нечетном количестве элементов в v2. Просто
Контейнеры vector и string
Контейнеры vector и string Все контейнеры STL по-своему полезны, однако большинство программистов С++ работает с vector и string чаще, чем с их собратьями, и это вполне понятно. Ведь контейнеры vector и string разрабатывались как замена массивов, а массивы настолько полезны и удобны, что
Совет 16. Научитесь передавать данные vector и string функциям унаследованного интерфейса
Совет 16. Научитесь передавать данные vector и string функциям унаследованного интерфейса С момента стандартизации С++ в 1998 году элита С++ настойчиво подталкивает программистов к переходу с массивов на vector. Столь же открыто пропагандируется переход от указателей char* к объектам
Совет 18. Избегайте vector<bool>
Совет 18. Избегайте vector<bool> Vector<bool> как контейнер STL обладает лишь двумя недостатками. Во-первых, это вообще не контейнер STL. Во-вторых, он не содержит bool.Объект не становится контейнером STL только потому, что кто-то назвал его таковым — он становится контейнером STL лишь
Совет 43. Используйте алгоритмы вместо циклов
Совет 43. Используйте алгоритмы вместо циклов Каждому алгоритму передается по крайней мере одна пара итераторов, определяющих интервал объектов для выполнения некоторой операции. Так, алгоритм min_element находит минимальное значение в интервале, алгоритм accumulate вычисляет
Совет 44. Используйте функции контейнеров вместо одноименных алгоритмов
Совет 44. Используйте функции контейнеров вместо одноименных алгоритмов Некоторые контейнеры содержат функции, имена которых совпадают с именами алгоритмов STL. Так, в ассоциативных контейнерах существуют функции count, find, lower_bound, upper_bound и equal_range, а в контейнере list
Вектор (Vector)
Вектор (Vector) vector - вид последовательности, которая поддерживает итераторы произвольного доступа. Кроме того, он поддерживает операции вставки и удаления в конце с постоянным (амортизированным) временем; вставка и удаление в середине занимают линейное время. Управление
3.10. Класс vector
3.10. Класс vector Использование класса vector (см. раздел 2.8) является альтернативой применению встроенных массивов. Этот класс предоставляет гораздо больше возможностей, поэтому его использование предпочтительней. Однако встречаются ситуации, когда не обойтись без
6.9 Класс String
6.9 Класс String Вот довольно реалистичный пример класса строк string. В нем производится учет ссылок на строку с целью минимизировать копирование и в качестве констант применяются стандартные символьные строки С++.#include «stream.h» #include «string.h»class string (* struct srep (* char* s; // указатель на