|
|
Регистрация Восстановить пароль |
Регистрация | Задать вопрос |
Заплачу за решение |
Новые сообщения |
Сообщения за день |
Расширенный поиск |
Правила |
Всё прочитано |
|
Опции темы | Поиск в этой теме |
29.08.2021, 22:02 | #1 |
Новичок
Джуниор
Регистрация: 29.08.2021
Сообщений: 3
|
Как правильно перегрузить swap для моего класса?
Здравствуйте.
Читаю книгу "C++ Primer. 5 edition". Нужно выполнить упражнение - перегрузить функцию swap() для своего класса. Для этого предлагается объявить её в том-же пространстве имён, что и сам класс. Я так и сделал. При вызове swap() действительно вызывается перегруженая функция, а при вызове std::swap() - соответственно, std::swap(). Но при вызове std::sort() обмены осуществляются только с помощью std::swap(), что неприемлемо - должна вызываться специальная функция. Нашёл готовый код упражнений к книге: https://github.com/Mooophy/Cpp-Prime...ch13/ex13_31.h https://github.com/Mooophy/Cpp-Prime...13/ex13_31.cpp Пишу в Visual Studio Community 2019. Архив с проектом: vopros_swap.rar. Там есть нюанс: в одной папке лежат файлы моего класса HasPtr (HasPtr.h, HasPtr.cpp) и скачанные по ссылке (ex13_31.h, ex13_31.cpp). Я исключаю ненужные файлы из проекта (не удаляю), а нужные - включаю. И так переключаюсь между своим кодом и скачанным. В скачанный код добавил вывод отладочных сообщений. Заранее благодарен. |
31.08.2021, 07:38 | #2 |
фрилансер
Участник клуба
Регистрация: 11.10.2019
Сообщений: 1,010
|
SourceOfDeath, вот, пробую два файла по ссылке:
https://onlinegdb.com/WGQdbMj7r вывод Код:
а почему в операторе < не проверяется ps на nullptr? если ответ "он всегда заполнен", то следует вопрос - а зачем ps вообще указатель? Почему не поле? Ведь это многое упрощает https://onlinegdb.com/olLSsG-W9 Последний раз редактировалось Алексей1153; 31.08.2021 в 07:47. |
31.08.2021, 21:07 | #3 | ||||
Новичок
Джуниор
Регистрация: 29.08.2021
Сообщений: 3
|
Спасибо, Алексей1153, что попытались помочь.
Цитата:
-вызывается копирующий конструктор -вызывается два раза оператор присваивания -вызывается деструктор. Это свидетельствует, что в std::sort вызывается std::swap, а не перегруженная специальная функция. Наверно, я затупил, что не вставил в пост с вопросом исходный код. тестовая программа: Код:
Код:
Код:
Цитата:
Цитата:
Цитата:
Последний раз редактировалось SourceOfDeath; 31.08.2021 в 21:21. |
||||
31.08.2021, 21:53 | #4 |
фрилансер
Участник клуба
Регистрация: 11.10.2019
Сообщений: 1,010
|
SourceOfDeath, я попробовал, и вижу, что в std::sort не использует std::swap, он там, похоже, использует оператор и конструктор перемещения, которые у тебя не определены явно. А должны бы.
Подтверждение подозрения: если в файле HasPtr.h открыть строки 14, 15 или сразу обе, то код перестаёт компилиться (код по ссылке можно fork и править) https://onlinegdb.com/I226nVguv также у тебя забыт конструктор по умолчанию (я добавил) Есть такое правило пяти дело тут не в учебности. Оператор перемещения, созданный компилятором по умолчанию, неправильно работает с полями - указателями. Из-за их кривого содержимого запросто возникнет неопределённое поведение - весь эксперимент будет неправильный к счастью, на практике такую кашу нет нужды делать, поскольку есть умные указатели и контейнеры Последний раз редактировалось BDA; 31.08.2021 в 22:16. |
02.09.2021, 21:15 | #5 | ||
Новичок
Джуниор
Регистрация: 29.08.2021
Сообщений: 3
|
Спасибо, Алексей1153.
Цитата:
Эти разделы есть в книге, но они позже. Цитата:
Код:
Наверно, хорошая практика - объявлять сразу все 5 методов как =deleted, и по мере осознанной надобности и требований компилятора, их реализовывать. У меня, получается, была возможность убедится в том, что std::sort не использует swap: нужно было поставить точку останова. Спасибо за потраченное на меня время. Надеюсь, не зря. Большую часть книги уже усвоил. |
||
03.09.2021, 07:39 | #6 | ||
фрилансер
Участник клуба
Регистрация: 11.10.2019
Сообщений: 1,010
|
Цитата:
хорошая практика - это правило ноля (упоминание есть по той же ссылке, где про правило пяти) Цитата:
и мне очень часто удаётся это правило использовать То есть, я практически не пишу конструкторы, операторы = и деструкторы, но если один из них потребовался, то все остальные явно упоминаю с =default очень редко бывает, что какую-нибудь из функций требуется удалить =delete |
||
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Шаблонная friend функция swap шаблонного класса | Aoizora | Общие вопросы C/C++ | 3 | 19.05.2017 17:14 |
Как правильно перегрузить << cout ? | Jugger | Помощь студентам | 1 | 13.03.2013 00:40 |
Как правильно перегрузить логические операции? | julia9311 | Общие вопросы C/C++ | 8 | 15.01.2013 13:44 |
Есть код,как правильно перегрузить конструктор | -ushёl- | Общие вопросы C/C++ | 9 | 08.07.2010 10:32 |
Как мне из моего класса вывести сообщение? | Utkin | Общие вопросы Delphi | 9 | 19.11.2009 14:43 |