HTML Diff
0 added 0 removed
Original 2026-01-01
Modified 2026-03-10
1 <p>Теги: c++, std::shared_ptr, с++11, класс, наследование, код, программирование, std::shared_ptr от this, указатель this</p>
1 <p>Теги: c++, std::shared_ptr, с++11, класс, наследование, код, программирование, std::shared_ptr от this, указатель this</p>
2 <p>Представим, что вот прямо сейчас в текущей строчке кода некоего класса нужно получить<strong>std::shared_ptr от this</strong>, чтобы передать его куда-нибудь. Создавать или нет?</p>
2 <p>Представим, что вот прямо сейчас в текущей строчке кода некоего класса нужно получить<strong>std::shared_ptr от this</strong>, чтобы передать его куда-нибудь. Создавать или нет?</p>
3 class SomeClass { public: using Ptr = std::shared_ptr&lt;SomeClass&gt;; Ptr createPtr() { return std::shared_ptr&lt;SomeClass&gt;{this}; } }<p>Вроде как правильный ответ - "нет". То есть не создавать. Потому что это чревато множеством проблем. Даже если всё сделать аккуратно. Что, если этот код уже вызывался и создаваемый сейчас<strong>std::shared_ptr</strong>будет уже вторым (третьим, четвертым…). Что произойдёт, когда придёт время этим указателям уничтожиться?</p>
3 class SomeClass { public: using Ptr = std::shared_ptr&lt;SomeClass&gt;; Ptr createPtr() { return std::shared_ptr&lt;SomeClass&gt;{this}; } }<p>Вроде как правильный ответ - "нет". То есть не создавать. Потому что это чревато множеством проблем. Даже если всё сделать аккуратно. Что, если этот код уже вызывался и создаваемый сейчас<strong>std::shared_ptr</strong>будет уже вторым (третьим, четвертым…). Что произойдёт, когда придёт время этим указателям уничтожиться?</p>
4 <p>Правильно,<strong>многократное освобождение</strong>одной и той же памяти. Ведь все созданные экземпляры<strong>std::shared_ptr</strong>являются независимыми, хотя и ссылаются на одну и ту же память (по указателю<strong>this</strong>).</p>
4 <p>Правильно,<strong>многократное освобождение</strong>одной и той же памяти. Ведь все созданные экземпляры<strong>std::shared_ptr</strong>являются независимыми, хотя и ссылаются на одну и ту же память (по указателю<strong>this</strong>).</p>
5 <h2>Что же делать?</h2>
5 <h2>Что же делать?</h2>
6 <p>Либо пересматривать дизайн, либо ознакомиться с новым (хотя уже не таким уж и новым) шаблонным классом, который присутствует, начиная с<strong>С++11</strong>- встречайте,<strong>std::enable_shared_from_this</strong>.</p>
6 <p>Либо пересматривать дизайн, либо ознакомиться с новым (хотя уже не таким уж и новым) шаблонным классом, который присутствует, начиная с<strong>С++11</strong>- встречайте,<strong>std::enable_shared_from_this</strong>.</p>
7 <p>Кроме претензии на звание самого длинного и непонятного названия, данный класс позволяет корректно создавать<strong>std::shared_ptr</strong>с использованием указателя<strong>this</strong>. Единственное требование - целевой класс должен быть наследником<strong>std::enabled_shared_from_this</strong>.</p>
7 <p>Кроме претензии на звание самого длинного и непонятного названия, данный класс позволяет корректно создавать<strong>std::shared_ptr</strong>с использованием указателя<strong>this</strong>. Единственное требование - целевой класс должен быть наследником<strong>std::enabled_shared_from_this</strong>.</p>
8 class SomeClass : public std::enable_shared_from_this&lt;SomeClass&gt; public: using Ptr = std::shared_ptr&lt;SomeClass&gt;; Ptr createPtr() { // Теперь корректно return shared_from_this(); } }<p>Немного более подробное описание можно найти<a>здесь</a>.</p>
8 class SomeClass : public std::enable_shared_from_this&lt;SomeClass&gt; public: using Ptr = std::shared_ptr&lt;SomeClass&gt;; Ptr createPtr() { // Теперь корректно return shared_from_this(); } }<p>Немного более подробное описание можно найти<a>здесь</a>.</p>
9 <p><em>Хотите узнать больше? Пишите в комментариях!</em></p>
9 <p><em>Хотите узнать больше? Пишите в комментариях!</em></p>
10  
10