Это даёт возможности очень гибко создавать всякие нетривиальные реализации интерфейсов.
Проблема в том, что нет никакого контроля — ни типа, ни значения аргументов такого конструктора.
Можно делать вот такие странные указатели: https://gcc.godbolt.org/z/ncz88ovW4
Тем не менее, заниматься самоприсваиванием с изменением указателя на агрегат — вполне легально и даже может иметь практический смысл: https://gcc.godbolt.org/z/edEzMe953
Но с такой же лёгкостью мы можем получить преждевременный конец времени жизни!
Что я и получил, сделав опечатку в реальном проекте!
Это напомнило мне как несколько лет назад попробовал перейти с именования членов класса с префиксом "m_" на суффикс "_". Т.е. попробовал вместо "m_cached_object" использовать "cached_object_". Ну типа модно, молодежно и нет отсылок к венгерской нотации.
Но быстро убедился, что этот самый суффикс "_" очень плохо читается в выражениях, поэтому так и продолжил жить с "m_".
Что-то мне кажется, что если бы изначально код писался так:
Здравствуйте, sergii.p, Вы писали:
SP>немного оффтопик, но вроде для кеша лучше подходит weak_ptr
Я тему времени жизни и условий обновления кеша тут не стал трогать, потому что совсем оффтопик.
Для логики "если в сокете есть новое, создадим новое, а иначе нужно взять старое" weak не подходит.
SP>И отдельный метод для нового конструктора тоже напрашивается. Только страшно его представить. Что-то типа такого:
Это не конструктор, это каст.
Когда агрегатом является база, то мы пользуемся тем, что есть конструктор shared_ptr<Base>(shared_ptr<Derived>)
а для всяких затейливых случаев — shared_pointer_cast.
В данном случае мы не создаём новый объект (make_shared), а создаём новый указатель к существующему объекту.
Да, пожалуй, завести функцию
template<class T, class M>
auto shared_member_ptr_cast(shared_ptr<T> p, M&(T::*m)) { return shared_ptr<M>{p, &p->*m}; }
template<class T, class M>
auto shared_member_fun_cast(shared_ptr<T> p, M&(T::*m)()) { return shared_ptr<M>{p, &(p->*m)()}; }
template<class T, class M>
auto shared_member_fun_cast(shared_ptr<T> p, M*(T::*m)()) { return shared_ptr<M>{p, (p->*m)()}; }
Здравствуйте, so5team, Вы писали:
S>Но быстро убедился, что этот самый суффикс "_" очень плохо читается в выражениях, поэтому так и продолжил жить с "m_".
+1, "_" как суффикс или префикс особенно плох для С++, где активно используются точки и "->".
на вкус и цвет...
я пробовал префикс подчеркивание впереди, как то глаза болят
поэтому суффиксом подчеркивание более красивее вышло
всяко лучше чем некоторые жабисты пихают везде this->
префикс m_ осталось только в одном проекте, который больше мне напоминает что это виндовый проект
Здравствуйте, reversecode, Вы писали:
R>префикс m_ осталось только в одном проекте, который больше мне напоминает что это виндовый проект
Префикс "m_" широко распространен, потому что это хорошо задокументированный стандард Qt.
Есть boost и Qt — либо_то, ЛибоДругое, все остальное от лукавого