|
1 / 1 / 0
Регистрация: 17.08.2020
Сообщений: 19
|
||||||
Дек (deque) - проверка знаний03.08.2021, 13:42. Показов 4449. Ответов 27
Добрый день/вечер/ночь.
Захотел воспользоваться знаниями опытных программистов этого форума и получить критику по ниже представленному "коду" ![]() Очень интересны абсолютно любые замечания, касающиеся стиля (если он там есть), работой с памятью и изобретенных велосипедов. Понимаю, что снизу представлен слишком скудноватый на строки код, чтобы по нему делать какие-то выводы, но уверен, что даже в нем находятся ошибки, которых я не замечаю ввиду своей неопытности. Итак, ниже я попытался написать дек при помощи динамического массива. Акцентирую внимание, что просматривал как работает стандартная библиотека <deque>, чтобы не отходить от её функционала. И немного глупо (по-моему мнению) получились методы begin() И end(), так как для очереди может быть выделена память из кучи, но заполнена только до половины, однако метод end() вернет значение на последний "мусорный" элемент очереди. Посмотрел и в <deque> работает это точно также, однако возможно чего то не заметил или не понял. Здесь ссылка на GitHub, если понадобится: https://github.com/spo1lsp0rt/deque_darr Ниже также находится вывод в консоль. Заранее благодарю за потраченное вами время ![]() Код: Кликните здесь для просмотра всего текста
Вывод в консоли: Кликните здесь для просмотра всего текста
Первое значение дека: 777 Промежуточное значение дека: 888 Последнее значение дека: 999 Пуст ли дек? Ответ: 0 Очистили дек. Пуст ли дек? Ответ: 1 Воспользовались assign(). Вывод дека: 9 9 9 9 9 Размер дека: 5 Воспользовались insert() для begin(). Вывод дека: 0 9 9 9 9 9 Воспользовались pop_back() и pop_front(). Вывод дека: 9 9 9 9 Воспользовались push_back() и push_front(). Вывод дека: -5 9 9 9 9 -5
0
|
||||||
| 03.08.2021, 13:42 | |
|
Ответы с готовыми решениями:
27
Deque (Дек) на двусвязном списке Создание ДЕК (как стэк только о двух концах) без <deque> Есть ли в Qt контейнер типа "Дек" (deque) или надо свой написать? |
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||
| 03.08.2021, 14:48 | ||
|
его нужно сначала проверить. исправить все явные ошибки, недочеты, а так же косяки, о которых тебе сообщает компилятор и только потом выкладывать на code-review. сейчас рассматривать твой код нет никакого смысла. вот когда ты исправишь все явные косяки, вот тогда и приходи.
0
|
||
|
1 / 1 / 0
Регистрация: 17.08.2020
Сообщений: 19
|
||||||
| 03.08.2021, 15:06 [ТС] | ||||||
|
Здравствуйте.
Если я правильно понял, то Вы имели ввиду предупреждения. Неправильно очищал память от данных. Однако в остальном код работает исправно. Исправления прикрепил ниже. Кликните здесь для просмотра всего текста
0
|
||||||
|
фрилансер
6449 / 5643 / 1129
Регистрация: 11.10.2019
Сообщений: 15,025
|
|
| 03.08.2021, 15:11 | |
|
spoilsport, по меньшей мере: конструктор по умолчанию, деструктор (освобождать память то надо?), использован
unsigned int вместо size_t ![]() Добавлено через 46 секунд NULL -> nullptr
0
|
|
|
1 / 1 / 0
Регистрация: 17.08.2020
Сообщений: 19
|
|||
| 03.08.2021, 15:51 [ТС] | |||
|
hoggy, Cпасибо за такой полезный сайт
Дело в том, что я пользуюсь лишь информацией, которую выдает мне мой компилятор и такого количества как у Вас - у меня не было. Сейчас просмотрю все и подправлю.Добавлено через 3 минуты Алексей1153,
0
|
|||
|
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
||
| 03.08.2021, 16:14 | ||
|
у компиляторов есть такое понятие: "уровень предупреждений". чем он выше, тем больше всяких косяков показывает компилятор. на максимальных уровнях компиляторы начинают докалебываться до каждой запятой. и именно такой уровень используют люди, которые хотят получить качественный код. как именно настраивается твой компилятор, описано в его документации. я не знаю какой у тебя компилятор, но если у тебя, например, компилятор Visual Studio, то почитать можно здесь. мой опыт показывает: что бы гарантировать высокое качество кода, недостаточно протестировать его только на одном компиляторе. необходимо запускать сразу множество сборок, на множестве разных компиляторов, во множестве различных конфигураций. и для всех этих сборок необходимо запускать юнит-тесты. и если хотя бы один компилятор покажет хотя бы один ворнинг - код отправится на доработку. если хотя бы одна сборка зафейлит хотя бы один юнит-тест - код отправится на доработку. мой опыт показывает: редко когда код сразу получается качественным. обычно на практике он по многу раз отправляется на доработку.
1
|
||
|
1 / 1 / 0
Регистрация: 17.08.2020
Сообщений: 19
|
||||||
| 03.08.2021, 17:34 [ТС] | ||||||
|
hoggy, спасибо большое, мне это поможет в будущем. Нашел как настроить "уровень предупреждений" в VS, классно, что теперь знаю о такой функции.
Исправил код, предупреждений больше не выдает, кроме совета об использовании списка инициализации для одного из конструкторов. Но я не могу переписать конструктор под такой механизм, потому что нужно использование цикла. Понимаю, что это не то, что нужно отправлять на кодревью. Необходимо просто практиковаться больше, но я надеялся подчеркнуть ошибки уже на этой стадии. И я уже узнал много чего интересного из этой темы ![]() Поэтому если у Вас будет свободное время, посмотрите пожалуйста мой бедо-код. Кликните здесь для просмотра всего текста
0
|
||||||
|
фрилансер
6449 / 5643 / 1129
Регистрация: 11.10.2019
Сообщений: 15,025
|
|||||||||
| 03.08.2021, 18:01 | |||||||||
|
там имеется в виду инициализация полей deque(const size_t& _size) :d_size{}, a{} { ну и ещё обращается внимание на порядок инициализации - он должен соответствовать порядку полей в классе а вообще, лучше прямо в месте объявления полей в классе инициализацию задать
1
|
|||||||||
|
Неэпический
|
|||||||||||
| 03.08.2021, 18:14 | |||||||||||
_deque.d_size окажется равным нулю, то в результате будет течь память, т.к. везде перед delete [] a идут проверки именно по d_size.
1
|
|||||||||||
|
1 / 1 / 0
Регистрация: 17.08.2020
Сообщений: 19
|
|||||||||||||||||||||||||||||||||
| 03.08.2021, 20:24 [ТС] | |||||||||||||||||||||||||||||||||
|
Алексей1153,
Кликните здесь для просмотра всего текста
Кликните здесь для просмотра всего текста
Добавлено через 19 минут Кликните здесь для просмотра всего текста
Когда же мы пишем как ниже, происходит именно передача адреса второго указателя в ячейку памяти первого указателя. И в таком случае, после удаления p2 указателя происходит разрыв связи первого указателя p1 со вторым p2. Кликните здесь для просмотра всего текста
Но когда я делал, как указали Вы, происходило так же как и во втором случае. Хотя казалось бы (как я понимаю) при a = temp создается копия temp'a и присваивается деку a. Вот я и встал в ступор. При очистке памяти временного temp дека почему то очищалась память и для основного дека. Когда же я убрал очистку временного дека delete[] temp, в основном деке оставались значения временного. Но я не понял почему, ведь по сути область видимости временного temp дека заканчивается при выходе из метода и он все равно очищается (поправьте, пожалуйста, если я косячник и не прав). Мне не понравилась вся эта ситуация, и поэтому я решил на время сделать именно ту запись, которую Вы видели. ![]() Добавлено через 22 минуты Добавлено через 19 минут Исправил все замечания выше. Еще раз благодарю за такую помощь, думаю мне это действительно помогает ![]() Кликните здесь для просмотра всего текста
0
|
|||||||||||||||||||||||||||||||||
|
фрилансер
6449 / 5643 / 1129
Регистрация: 11.10.2019
Сообщений: 15,025
|
|||||||||||||
| 03.08.2021, 20:37 | |||||||||||||
Сообщение было отмечено spoilsport как решение
Решениеconst size_t _size,const size_t pos (по значению)поскольку поля инициализированы в классе, то
тут не хватает константности пропущено обнуление кстати, в деструкторе можно вызвать clear()
1
|
|||||||||||||
|
1 / 1 / 0
Регистрация: 17.08.2020
Сообщений: 19
|
||||||||||||
| 03.08.2021, 20:58 [ТС] | ||||||||||||
|
Алексей1153,
![]() Спасибо Кликните здесь для просмотра всего текста
0
|
||||||||||||
|
фрилансер
6449 / 5643 / 1129
Регистрация: 11.10.2019
Сообщений: 15,025
|
||||||||||||||
| 03.08.2021, 21:16 | ||||||||||||||
|
Добавлено через 3 минуты
или даже вот так будет получше
1
|
||||||||||||||
|
Неэпический
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 03.08.2021, 22:13 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Сообщение было отмечено spoilsport как решение
Решение
spoilsport, предлагаю немного "порефакторить".
Давайте начнем с самого основного - имена. ![]() d_size и a.Не знаю что значит префикс d_ (наверное, "целое число"?), но из-за присутствия size в названии понятно что хранит переменная.А вот что такое a? Просто какая-то безликая буква.Такое название неприемлемо. Обозвали бы хотя бы data - было бы намного лучше.Предлагаю ввести концепцию - не статические данные класса начинать с префикса m_.Переименовываем a в m_data, и d_size в m_size.С параметрами функции та же беда - почему они то начинаются с подчеркивания, то нет ( _size и val)?Тоже переименовываем. Даже без всяких префиксов - просто уберем подчеркивание. Теперь пойдем по функциям.
<T> - нужно убрать. Внутри шаблона deque и так будет deque<T>.Почему конструктор копирования не использует список инициализации? В данном случае у вас размер и указатель являются не инициализированными и при присваивании может быть что угодно. Предлагаю воспользоваться делегированием:
int, size_t и т.д. - лучше передайте копию.В таком случае и const верхнего уровня можно убрать: deque(size_t size, const T& val) {У вас же шаблон, а конструктор deque(size_t size) предполагает, что объекту может быть присвоен ноль: m_data[i] = 0;.Можно также делегировать работу другому конструктору:
Это будет "особенность" данной реализации, связанная с тем, что вы не управляете жизнью отдельных объектов вручную. Оставим этот вопрос, когда научитесь - перепишите. ![]()
m_data либо указывает на выделенную память, либо равен nullptr.delete, примененный к нулевому указателю ничего не делает. Плюс у нас есть функция clear, почему бы не позвать её для очистки?
Давайте добавим константные версии данных функций:
Эти функции не меняют объект, также не возвращают наружу ничего, через что можно было бы поменять объект. Поэтому не будем добавлять константные версии этих функций. Мы просто на эти функции навесим const:
Это индекс первого и последнего элементов? Тогда как отличить пустой дек от дека с одним элементом? begin и end у них будут равны. Например в цикла ниже это приведет к катастрофе:
![]() Циклы в main сделаем через размер: for (size_t i = 0; i < dq.size(); i++)Далее insert. Претензии написал в комментариях:
Плюс мы можем использовать insert*:
pop_back та же история. Меняем:
m_data либо указывает на выделенную память, либо имеет значение nullptr:
Также почему оператор присваивания возвращает ссылку на элемент? Хотя в вашем случае return отсутствует вовсе.С учетом сказанного выше:
Итоговая реализация
Этот код можно (и нужно) еще допиливать и допиливать. Например, ручное управление объектами, перемещение, exception safety, и т.д. Добавлено через 4 минуты https://wandbox.org/permlink/Psgie8OM1CY7hsdE
1
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
1 / 1 / 0
Регистрация: 17.08.2020
Сообщений: 19
|
|||||||||||||
| 04.08.2021, 13:23 [ТС] | |||||||||||||
|
Алексей1153,
Croessmah, Константу тоже пока не разобрался почему не стоит передавать, считал это хорошим тоном, когда значение, не изменяемое в области видимости функции, помечают константным. ![]() ![]() Правда, большое спасибо Croessmah и Алексей1153 за ваше потраченное время и такой серьезный подход к разбору кода. Буду стараться, чтобы он теперь был чуточку лучше. Благодарю
0
|
|||||||||||||
|
Неэпический
|
||||
| 04.08.2021, 13:42 | ||||
size_t - достаточно легкий объект, вполне вероятно, что он вообще будет передан через регистр.Ссылка - тоже не большая, но внутри функции для получения значения нужно будет делать косвенное обращение. Оптимизатор может это всё оправить, а может и нет. А если передается копия объекта, то нет никакой необходимости делать параметр константным. Хотя если того требует code-style, то можно и написать. При этом внутри функции параметр будет константным. deque как раз "ручное" управление объектами. То есть объекты создаются и освобождаются по запросу. Если есть возможность, то другие объекты никак не затрагиваются.
1
|
||||
|
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
|
|||
| 04.08.2021, 13:45 | |||
|
Потому что вы вынуждаете компилятор везде в этих местах делать косвенный доступ. Добавлено через 2 минуты
1
|
|||
| 04.08.2021, 13:57 | |
|
0
|
|
|
1 / 1 / 0
Регистрация: 17.08.2020
Сообщений: 19
|
||||
| 04.08.2021, 15:09 [ТС] | ||||
|
Croessmah,
DrOffset,
0
|
||||
| 04.08.2021, 15:09 | |
|
Помогаю со студенческими работами здесь
20
Хранение в контейнере deque целых чисел и проверка основных операций Проверка знаний по C++
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
|
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11
— это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
|
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11
Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
|
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
|
|
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/
O1rJuneU_ls
https:/ / vkvideo. ru/ video-115721503_456239114
|
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ВВЕДЕНИЕ
Введу сокращения:
аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
|
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi
ветка по-частям.
коммит Create переделка под биомассу. txt
вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
|
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ *
Дана цепь постоянного тока с сопротивлениями и источниками (напряжения, ЭДС и тока). Найти токи и напряжения во
всех элементах. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и. . .
|