Russian Qt Forum
Апрель 28, 2024, 02:19 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: c++ 11/14 vs "старый c++"  (Прочитано 14481 раз)
AzazelloAV
Гость
« : Июнь 21, 2017, 19:25 »

Данный пост не спрашивает никаких решений. Считайте это рассуждения вслух - кто как.

Классика RAII:
Код:
class Test
{
public:
    Test() { m_data = new Data; }
   ~Test() { delete mData; }
private:
    Data* m_data = 0;
}

По новому RAII:
Код:
class Test
{
public:
    Test();
   ~Test() = default
private:
    std::unique_ptr<Data> m_data;
    or
    QScopedPointer<Data> m_data;
}

Понятно, все мы зависим от стиля написания, если проект не наш.
Поэтому, давайте считать что это ваш проект.

Отказался от использования unique_ptr для таких (именно таких случаях, пусть это будет PImpl)
1.  Отсутсвует подсветка синтаксиса для m_data
2. Дебаг по коду позволяет ознакомиться с вырвиглазным кодом stl

Сразу отвечу противникам - даже если вы пропустили ваш делете, никто сейчас не программирует без профилировщика и не заметить пропуск такого явного удаления просто невозможно, причем в самом начале.

P.S. Пользуюсь ништяками c++11 давно.
« Последнее редактирование: Июнь 21, 2017, 19:47 от AzazelloAV » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #1 : Июнь 21, 2017, 20:18 »

1. Лечится включением шланг модели кода
2. Должно лечиться gdb pretty printers, нет?

Ну а так, unique_ptr exception-safe, а ручной Pimpl нет (например, тров в конструкторе после new)
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Июнь 22, 2017, 08:27 »

Причем тут подсветка если ф-ционал разный.
Код:
    std::unique_ptr<Data> m_data;
    or
    QScopedPointer<Data> m_data;
Эти варианты неравноценны. QScopedPointer можно свободно копировать и отдавать по значению, а unique_ptr нет.

Вообще иметь unique_ptr членом как-то не очень, есть довольно стойкий рефлекс что оператор = и конструктор копирования принимают константные аргументы, а здесь это не так. Выносить моск ради жалкого delete - не вижу смысла
Записан
AzazelloAV
Гость
« Ответ #3 : Июнь 22, 2017, 10:33 »

1. Лечится включением шланг модели кода
2. Должно лечиться gdb pretty printers, нет?

Поясните подробней.
И, кстати, не всегда же мы в одной среде сидим, в т.ч. в  разных ОС.

Ну а так, unique_ptr exception-safe, а ручной Pimpl нет (например, тров в конструкторе после new)

Согласен с вашим примером. НО, это только единственный пример, который можно привести.

Ну и конечно же, я точно уверен, что у вас стиль программирования таков, что никаких исключений в конструкторе Вы себе не позволяете.
Записан
AzazelloAV
Гость
« Ответ #4 : Июнь 22, 2017, 10:35 »

Цитировать
Эти варианты неравноценны. QScopedPointer можно свободно копировать и отдавать по значению, а unique_ptr нет.

Вообще иметь unique_ptr членом как-то не очень, есть довольно стойкий рефлекс что оператор = и конструктор копирования принимают константные аргументы, а здесь это не так. Выносить моск ради жалкого delete - не вижу смысла

Простите, но вообще ничего не понял.
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #5 : Июнь 22, 2017, 12:02 »


Поясните подробней.
И, кстати, не всегда же мы в одной среде сидим, в т.ч. в  разных ОС.
Не, ну если у вас не креатор, то могу советовать погуглить как починить вашу иде:) А так, иде, не умеющая в вумные указатели - не нужна:)
А так, есть питоновские скрипты для gdb, которые "учат" его разворачивать умные указатели как обычные (без кишков). Как их подключить к иде я сходу не скажу (даже для креатора, давно это было). Вроде бы, под линухом достаточно поставить пакет. Под вин/мак вообще хз.

Согласен с вашим примером. НО, это только единственный пример, который можно привести.
Ну, мой пример выстрадан болью, а ваши надуманы:)

Ну и конечно же, я точно уверен, что у вас стиль программирования таков, что никаких исключений в конструкторе Вы себе не позволяете.

Почему нет? (Абстрагируемся о том, что исключения вообще с Qt кодом не дружат (я уже давно не пишу на Qt, к сожалению)). Это единственный способ сообщить об ошибке в конструкторе. Альтернативой будет только богомерзкий метод bool init(); который можно внезапно забыть вызвать. Или вызвать дважды. В общем, вы поняли, придётся писать много документации о том, как использовать ваш класс. Вместо банального инстанцирования.
« Последнее редактирование: Июнь 22, 2017, 12:03 от Авварон » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 579


Просмотр профиля
« Ответ #6 : Июнь 22, 2017, 12:55 »

Отказался от использования unique_ptr для таких (именно таких случаях, пусть это будет PImpl)
...

Программировать можно как угодно, лишь бы программа работала корректно).
А вот для ее дальнейшего сопровождения - это создает существенные трудности, даже если программа твоя.

В случае raw указателя ( Data * ) невозможно с ходу понять, что имеется в виду - значение, массив значений, полюс ассоциативной связи, композитная агрегация, совместная агрегация. Что?
Использование std::unique_ptr хоть как-то ограничивает этот перечень, не говоря уже о неявном new/delete.

Даже стандарт С++11/14/17 не доработан до такой степени, чтобы можно было четко отделять мух от котлет

Код
class Test
{
public:
   Test();
   ~Test() = default
private:
   Attribute< Data > m_attribute; // данные, не участвующие в ассоциативных связях
   Unique<Data> m_unique; // полюс ассоциативной связи копозитной агрегации (участник ассоциативных связей)
   Shared<Data> m_shared; // полюс ассоциативной связи обобщенной агрегации (участник ассоциативных связей)
   Assocc<Data> m_assocc; // полюс ассоциативной связи, не являющейся агрегацией (участник ассоциативных связей)
}
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #7 : Июнь 22, 2017, 13:13 »

Вместо Assocc можно использовать ссылку (std::reference_wrapper)
Вместо Attribute - value-based классы.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Июнь 22, 2017, 13:13 »

полюс ассоциативной связи,
А что это? Расскажите. Спасибо

Использование std::unique_ptr хоть как-то ограничивает этот перечень, не говоря уже о неявном new/delete.
Думаю ключевое слово "хоть как-то". Да, заявили что владеем, отвечаем за создание/удаление. Другие достижения? (не наблюдаю)
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 579


Просмотр профиля
« Ответ #9 : Июнь 22, 2017, 13:46 »

Вместо Assocc можно использовать ссылку (std::reference_wrapper)
Вместо Attribute - value-based классы.

В простейшем случае можно, а в общем недостаточно).

Например, для обобщенной агрегации в качестве ссылки нужно бы использовать weak_ptr. Даже для композитной агрегации может потребоваться использование связки shared_ptr/weak_ptr вместо unique_ptr/reference_wrapper.
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 579


Просмотр профиля
« Ответ #10 : Июнь 22, 2017, 14:13 »

полюс ассоциативной связи,
А что это? Расскажите. Спасибо

Это понятия ООП. Между объектами могут существовать отношения.
Одним из видов отношений являются ассоциации. Ассоциация означает, что экземпляры одного класса связаны с экземплярами другого класса.
Экземпляр ассоциации (связь) состоит из полюсов, связанных с объектами.
Часто ассоциативная связь реализуется в виде, когда её полюсы принадлежат одному и более объектам, участвующим в ассоциативной связи.

Частным случаем ассоциаций являются биполярные ассоциации.
Частным случаем биполярной ассоциации является ассоциация агрегации (отношение Часть/Целое). Целое определяет время жизни Части.
Со стороны Целого полюс ассоциативной может быть либо unique (уникальная или композитная агрегация), либо shared (обобщенная агрегация).
Со стороны Части может либо не быть полюса, либо быть none (полюс не агрегации).

Хотя в стандарт и ввели unique_ptr и shared_ptr, но кроме названий ничего общего полюсами уникальной (композитной) и обобщенной агрегации они не имеют.
При этом они могут быть использованы при реализации этих самых полюсов ассоциативных связей (наравне с raw указателем)) ).
« Последнее редактирование: Июнь 22, 2017, 14:15 от ssoft » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #11 : Июнь 22, 2017, 14:22 »

Частным случаем биполярной ассоциации является ассоциация агрегации (отношение Часть/Целое). Целое определяет время жизни Части.

Кажется, тут вы врёте. Из вики:
Цитировать
Агрегация (агрегирование по ссылке) — отношение «часть-целое» между двумя равноправными объектами, когда один объект (контейнер) имеет ссылку на другой объект. Оба объекта могут существовать независимо: если контейнер будет уничтожен, то его содержимое — нет.
Цитировать
Композиция (агрегирование по значению) — более строгий вариант агрегирования, когда включаемый объект может существовать только как часть контейнера. Если контейнер будет уничтожен, то и включённый объект тоже будет уничтожен.
Цитировать
Aggregation differs from ordinary composition in that it does not imply ownership. In composition, when the owning object is destroyed, so are the contained objects. In aggregation, this is not necessarily true
« Последнее редактирование: Июнь 22, 2017, 14:24 от Авварон » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3258


Просмотр профиля
« Ответ #12 : Июнь 22, 2017, 14:34 »

На самом деле, не уверен, что отношения агрегации/композиции должны быть частью стандарта.
Вот например, композиция один ко-многим может быть реализована десятком способов:
Код:
class Whole
{
    std::vector<Part> parts0;
    std::vector<std::unique_ptr<Part>> parts1;
    std::deque<std::unique_ptr<Part>> parts2;
    std::map<PartId, std::unique_ptr<Part>> parts5;
    std::unordered_map<PartId, std::unique_ptr<Part>> parts6;
    // ...
};
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Июнь 22, 2017, 15:02 »

Экземпляр ассоциации (связь) состоит из полюсов, связанных с объектами.
Часто ассоциативная связь реализуется в виде, когда её полюсы принадлежат одному и более объектам, участвующим в ассоциативной связи.
Так и не понял что такое (или где) "полюс". Ну да ладно, все равно спасибо

Вот shared_ptr имеет weak_ptr, полезная вещь, по крайней мере четко видно что владелец извне. А почему unique_ptr не имеет подобного? Если его надо где-то задействовать - выходит отдавай голый. Тогда за что боролись?
Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 579


Просмотр профиля
« Ответ #14 : Июнь 22, 2017, 15:23 »

Так и не понял что такое (или где) "полюс". Ну да ладно, все равно спасибо

Полюс - это значение, реализующее связь с объектом (ссылка, указатель, сам экземпляр объекта).

То есть, например, unique_ptr является полюсом, если его внутреннее значение задействовано в ассоциативных связях.
Тот же unique_ptr является просто атрибутом, если его внутреннее значение не задействовано в ассоциативных связях.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.064 секунд. Запросов: 23.