Re[20]: Исповедь C++ника
От: Тёмчик Австралия жж
Дата: 26.12.20 09:35
Оценка: -1 :))
Здравствуйте, so5team, Вы писали:

Тё>>>>Ну смотри — удаление подписки. Как ты её собрался искать в контейнере? Какова стоимость?


S>>>Зависит от обстоятельств. К которым мы перейдем ниже, там где фрагменты кода появятся.

Тё>>Не юли.

S>Сперва прочитайте то, что вам пишут, потом уже отвечайте.


OMG да я понял, что вы давно слились, когда запели про "10 подписок".

S>>>Гораздо более серьезно, чем когда вы заявляете, что C++ не используется для рилтайма.

Тё>>Я заявлял, что в ядре не место C++. Именно полноценному C++, ибо C-с-классами не является полноценным C++ в понимании стандарта C++.

S>Вы заявили следующее (http://rsdn.org/forum/job/7907304.1):
Автор: Тёмчик
Дата: 17.12.20

Реалтайм бывает soft и hard. Soft вообще похрен на чём делать, а для hard плюсы не подходят (если не рассматривать C с классами).

>> Реалтаймовые системы не на плюсах делают.


S>Все ходы записаны.


Тё>>И часто вас жизнь заставляет замерять оверхед на 10 элементах?


S>Нет. Но бывает.


S>>>Ибо в C++ Node<T> хранил бы экземпляр T не по указателю, а по значению. А то у вас получится по две аллокации на объект в списке: первая для самого T, вторая для Node<T>.

Тё>>Ты в курсе, что есть указатель на T, в данном случае? Может быть, это указатель на какой-то родительский объект или другую подписку, которого можно дёрнуть для оповещения об изменениях. Может быть, его и заполнять необязательно.

S>Тёмчик, давайте говорить о примере от B0FEE664. В котором под T можно подразумевать только std::pair<OnPress, void*>. Если вы хотите ввести в обсуждение еще что-то, то потрудитесь это описать, чтобы люди понимали, о чем речь.

Почему у вас onpress в типе? Почему у вас void*? Вы что, про статическую типизацию не слыхали?
По уму, там интерфейс нужен типа такого
interface Subscriber<T> {
    void accept(T const &arg);
}


Тё>>Чувачелло, величина твоего невежества зашкаливает. Но я же привёл ссылку. Сложно прочитать?

Тё>>

Тё>>>>https://en.wikipedia.org/wiki/Sentinel_node#Linked_list_implementation


S>Т.е. вы для хранения списка подписок предлагаете хранить еще и специальный sentinel node?

Я не "предлагаю" — это оптимизация связного списка для упрощения его операций, почитайте, учиться ведь всегда полезно.

Тё>>Если пописчиков немного, то не стоит заморачиваться на алгоритмическую сложность.


S>Если вы еще не заметили, то речь идет не про алгоритмическую сложность, а о стоимости по памяти и времени исполнения. В случаях, когда подписчиков немного.


Тё>>Кто управляет временем жизни callback?


S>Подписчик.

Ну вот ваш подписчик должен хранить интерфейс для отписки. Может хранить пачку таких подписок в списке, и отписываться в деструкторе, например. Тоже такой наивный способ. Элегантный способ в http://reactivex.io/ — использовать оператор takeUntil().

S>>>Если достаточно всего лишь указателя на callback, то хранение для каждой подписки Subscription -- это дополнительная головная боль. Особенно в C++, где ничего не защищает от обращения к повисшим указателям.

Тё>>У хорошего плюсника не бывает тухлых указателей. Вы к таким определённо не относитесь.

S>Без разницы к каким вы меня относите. Суть в том, что такая проблема есть. И решений, которые ее провоцируют, следует избегать. Тогда будет не важно, хороший плюсник работает с кодом или нет.


S>>> Использовали экземпляр subscription для отписки один раз, а потом, по ошибке, сделали отписку повторно. И что будет в итоге?

Тё>>В итоге будет nullptr и это правильно. Ибо кривые руки повторно-вызывальщиков отписок, релизов, диспозов и прочих делетов нужно испрямнять жёстко и без церемоний.

S>На словах все герои. Только вот если у вас отписка работает через поиск (по указателю на callback или по какому-то уникальному Id), то она оказывается более устойчивой к подобным ошибкам.

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

S>Кроме того, в C++ объекты по умолчанию копируются. Т.е. если есть:

S>
S>class Subscription {
S>  Node * node_;
S>public:
S>  ...
S>  void unsubscribe() {
S>    if(node_) {
S>      ...
S>      node_ = nullptr;
S>    }
S>  }
S>};
S>

S>То потребуется еще позаботится о том, чтобы объекты Subscription не копировались. Потому что зануление node_ в копии никак не скажется на исходном объекте. А до C++11 нормальных средств для этого в языке не было (а код от B0FEE664 явно написан для C++98).
Возвращается ссылка на интерфейс Subscription. Это может быть наследник от Node имплементирующий Subscription. О каком каком копировании вы поёте?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.