С Новым годом! Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
Диванный эксперт
Эксперт С++
 Аватар для Max Dark
2550 / 2064 / 971
Регистрация: 09.10.2013
Сообщений: 4,793
Записей в блоге: 4

Использование enable_shared_from_this совместно с custom deleter

14.09.2023, 23:16. Показов 1556. Ответов 3

Студворк — интернет-сервис помощи студентам
Доброго времени суток.

У std::sharde_ptr есть возможность указать пользовательский deleter.

Так же есть std::enable_shared_from_this.

Возникли вопросы:
  • Будет ли использоваться custom deleter после использования shared_form_this?
  • Безопасно ли их совместное условие?
  • Почему такой ответ?

Предполагаемое использование:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// interface.hxx
 
#include <memory>
 
struct A
{
    using ptr = std::shared_ptr<A>;
 
    static ptr create();
    virtual ptr demo() = 0;
 
protected:
    static void destroy(A* a);
    virtual ~A();
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// interface.cxx
 
#include "interface.hxx"
 
struct B: A, std::enable_from_this()
{
    ptr demo() override
    {
        return shared_from_this(); // <<< Is it safe??
    }
 
};
 
A::~A() = default;
 
A::ptr A::create() { return {new B, &A::destroy}; }
 
void A::destroy(A* a)
{
    // some cleanup code
 
    delete a;
}
Я хочу использовать эту связку, чтобы возвращать shared_ptr из dll и и при этом для создания/удаления использовался аллокатор из этой же dll
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.09.2023, 23:16
Ответы с готовыми решениями:

Custom deleter умного указателя
Нужен ли custom deleter в данном случае? Если да, то как его реализовать? Стандарт c++11 Заранее спасибо. int somef(int size) { ...

Использование if совместно с case
Добрейшего времени бытия, товарищи! У меня возник вот такой вопрос:&quot;Можно ли сделать IF по результату выбора какого-то...

Использование DDR3 совместно с DDR3L
Приветствую. Купил dd3l, дома выяснилось, что в asus k55d стоят 2 плашки ddr3. Вставлял совместно и только одну ddr3l, не пошло....

3
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
15.09.2023, 00:27
Max Dark, безотносительно вопроса, сама по себе идея возвращать shared_ptr из dll крайне спорная. Хотя бы потому, что проблема, которую вы решаете с помощью custom deleter`а, никуда не денется, а просто перейдет на уровень самого shared_ptr - аллокация счетчика будет подвержена ей. К тому же layout shared_ptr скорее всего не будет переносим между разными компиляторами.

Поэтому совет: для стабильной работы в DLL, ничего лучше COM-like класса с внутренним счетчиком ссылок и inline обертки a-la intrusive_ptr не придумано.
2
Диванный эксперт
Эксперт С++
 Аватар для Max Dark
2550 / 2064 / 971
Регистрация: 09.10.2013
Сообщений: 4,793
Записей в блоге: 4
15.09.2023, 00:59  [ТС]
DrOffset, предполагается, что будет использоваться один и тот же компилятор для всех модулей.
Основная причина наличия таких модулей - загрузка по необходимости.

Добавлено через 7 минут
DrOffset, аллокация control block как я понимаю так же будет происходить на стороне DLL, так как A::ptr A::create() { return {new B, &A::destroy}; } будет внутри библиотеки.
0
19491 / 10097 / 2460
Регистрация: 30.01.2014
Сообщений: 17,805
15.09.2023, 09:57
Цитата Сообщение от Max Dark Посмотреть сообщение
аллокация control block как я понимаю так же будет происходить на стороне DLL
А деаллокация? Реализация может конечно ее предусматривать в правильном месте, но гарантий никаких нет.
Так что я бы на вашем месте отказался от share_ptr для использования с объектами в dll.
Заодно и вопрос ваш про enable_form_this решится сам собой, для интрузивных счетчиков нет этой проблемы.
Весь контроль за местом освобождения объекта будет полностью в ваших руках.

Добавлено через 27 минут
Max Dark,
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <cassert>
#include <utility>
 
class IRefCnt
{
public:
    virtual void addRef() = 0;
    virtual void remRef() = 0;
};
 
template <typename IObj>
class RefCnt : public IObj
{
protected:
    RefCnt() : m_refCnt()
    {}
 
    void addRef() override
    {
        ++m_refCnt;
    }
    void remRef() override
    {
        if(--m_refCnt == 0)
        {
            delete this;
        }
    }
 
private:
    int m_refCnt;
};
 
template <typename IObj>
class RefCntPtr
{
public:
    RefCntPtr(IObj* p = nullptr) : m_ptr(p)
    {
        if(m_ptr) m_ptr->addRef();
    }
    ~RefCntPtr()
    {
        if(m_ptr) m_ptr->remRef();
    }
    RefCntPtr(RefCntPtr const& other) : m_ptr(other.m_ptr)
    {
        if(m_ptr) m_ptr->addRef();
    }
    RefCntPtr& operator=(RefCntPtr const& other)
    {
        if(this != &other)
            RefCntPtr(other).swap(*this);
        return *this;
    }
    void swap(RefCntPtr& other)
    {
        std::swap(m_ptr, other.m_ptr);
    }
 
    IObj* operator->()
    {
        assert(m_ptr != nullptr);
        return m_ptr;
    }
    
private:
    IObj* m_ptr;
};
 
class ISomeDll;
 
extern "C" ISomeDll* createSomeDll();
 
class ISomeDll : public IRefCnt
{
public:
    using IPtr = RefCntPtr<ISomeDll>;
 
    IPtr demo() // NVI
    {
        return IPtr( this );
    }
    static IPtr create()
    {
        return IPtr( createSomeDll() );
    }
 
    virtual void test() = 0;
 
protected:
    virtual ~ISomeDll() = default;
};
 
//........................
// cpp
#include <iostream>
 
class SomeDll : RefCnt<ISomeDll>
{
    friend ISomeDll* createSomeDll();
public:
    void test() override
    {
        std::cout << "SomeDll::test\n";
    }
    ~SomeDll()
    {
        std::cout << "SomeDll destroyed\n";
    }
};
 
ISomeDll* createSomeDll()
{
    return new(std::nothrow) SomeDll();
}
 
int main()
{
    ISomeDll::IPtr p = ISomeDll::create();
 
    p->test();
 
    ISomeDll::IPtr p1 = p->demo();
 
    p1->test();
}
https://wandbox.org/permlink/Z01yFAWrllC6GRTE
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.09.2023, 09:57
Помогаю со студенческими работами здесь

Использование TOP и GROUP BY совместно
Мне нужно получить по одной записи из каждой группы в таблице. Например, А Б В 1 2 3 2 3 3 3 6 4 4 5 ...

Использование нескольких языков совместно с C#
Ребята, я слышал что в С# можно использовать несколько языков, что например можно часть кода написать на С++ а часть на С#. Только на этом...

Использование Entity Framework совместно с SQLite
Подскажите пожалуйста как совместить их? Только при создании БД из графического интерфейса (через диаграмму). Я еще только только впервые...

Использование VB или VB .NET совместно с IIS
В указанных программах есть поддержка для упрощенного написания ASP скриптов из этих оболочек. VB6.0 требует IIS версии 3.0 и выше но мою...

Использование Java-кода совместно с Joomla, например
Всем привет. Есть код, написанный на облаке SalesForce. В этом облаке получается логика пишется на Java подобном языке + встроенная БД +...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
Расчёт токов в цепи постоянного тока
igorrr37 05.01.2026
/ * Дана цепь постоянного тока с сопротивлениями и напряжениями. Надо найти токи в ветвях. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа и решает её. Последовательность действий:. . .
Новый CodeBlocs. Версия 25.03
palva 04.01.2026
Оказывается, недавно вышла новая версия CodeBlocks за номером 25. 03. Когда-то давно я возился с только что вышедшей тогда версией 20. 03. С тех пор я давно снёс всё с компьютера и забыл. Теперь. . .
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru