Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
1

Запрет shared_ptr быть наследником определённого класса

26.04.2017, 22:10. Показов 881. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день,

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <memory>
 
class A
{
};
 
class B : public A
{
};
 
template <typename T>
class MySharedPtr : public std::shared_ptr<T>
{
    static_assert( !std::is_base_of<A, T>::value, "MySharedPtr can't be base of A" );
};
 
int main()
{
    MySharedPtr<int> a;
    MySharedPtr<B> b;   
}
будет ли данный код работать по задумке, которую он имеет - хочу запретить создавать std::shared_ptr для типов у которых есть свой RefCounter
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.04.2017, 22:10
Ответы с готовыми решениями:

Как обратится к обьекту класса, являющегося наследником абстрактного класса
Здравствуйте! У меня есть 4 класса: один виртуальный, следующие 2 - наследуют виртуальный класс и...

как узнать,является данный объект класса А1 наследником класса А2
Всем привет)есть классы S, A1, A2, B1, B2. Иерархия наследования следующая S - Является...

Использование конструктора базового класса наследником
Доброго дня, коллеги! Решал одну задачку и столкнулся с проблемой. По условию дан класс String,...

Разработать класс ForeignBilet, являющийся наследником класса Bilet
Разработать класс ForeignBilet, являющийся наследником класса Bilet (билет), добавив следующие...

14
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
26.04.2017, 23:35 2
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
хочу запретить создавать std::shared_ptr для типов у которых есть свой RefCounter
так и нужно запрещать не наследников,
а тех, у кого есть свой RefCounter.

для этого нужно четко обозначить признаки:
как определить, есть ли у класса RefCounter?
может быть у класса с RefCounter есть какой то особый метод?
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
27.04.2017, 00:00  [ТС] 3
hoggy, так как я знаю, что вы знакомы с cocos2dx - проблема на лицо
Если хранить поле класса как умный указатель и случайно/неслучайно через некоторое время добавить его в Node ( addChild(ptr) )
то память будет уничтожена дважды, когда умрёт родительский Node и при очистки умного указателя - хочу защитить самого себя от самого себя!

Данный способ сработает? Если я когда-то добавлю классу признаки cocos2dx - везде где были "мои" умные указатели на этот класс начнётся дикая ругать
0
Эксперт С++
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
27.04.2017, 02:00 4
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Если хранить поле класса как умный указатель и случайно/неслучайно через некоторое время добавить его в Node ( addChild(ptr) )
то память будет уничтожена дважды, когда умрёт родительский Node и при очистки умного указателя - хочу защитить самого себя от самого себя!
не понял смысла проблемы.
1
5231 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,113
Записей в блоге: 2
27.04.2017, 08:39 5
Очень похоже, что проблемы нет, а задача надуманная. С++ не простой язык, постоянно приходиться думать о том, что и как ты пишешь. Попытка дать программисту возможность не думать неоправданно усложняет все вокруг.
Имхо - я бы так не заморачивался, кто-то накосячил - сам дурак.

Добавлено через 4 минуты
а так можно свой make_shared, но это не дает 100% защиты, кто-то может создать shared_ptr без хелпера, но свой класс для shared_ptr также не дает 100% защиты, кто-то может создать shared_ptr и без него.

Добавлено через 4 минуты
ну и совсем дурной вариант - добавить в std специлизацию (через enable_if<has_ref_counter<T>>>), но за это по рукам бьют, в лучшем случае сразу.
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
27.04.2017, 11:41  [ТС] 6
Цитата Сообщение от hoggy Посмотреть сообщение
не понял смысла проблемы.
As always .....

Цитата Сообщение от Kastaneda Посмотреть сообщение
Имхо - я бы так не заморачивался, кто-то накосячил - сам дурак.
Так можно написать про все использования static_assert

Цитата Сообщение от Kastaneda Посмотреть сообщение
кто-то может создать shared_ptr без хелпера
поиск std::shared_ptr по проекту подскажет

Цитата Сообщение от Kastaneda Посмотреть сообщение
но свой класс для shared_ptr также не дает 100% защиты
в этом и заключается тема, если в проекте на уровне кодинг стайла будет запрещено использовать стандартные умные указатели - всё же норм будет?

Цитата Сообщение от Kastaneda Посмотреть сообщение
ну и совсем дурной вариант
0
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
27.04.2017, 11:46 7
Производные сущности не могут контролировать подобные аспекты
Если вам не нужно наследоваться от шаред пойнтера - просто не делайте этого
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
27.04.2017, 11:55  [ТС] 8
Цитата Сообщение от Undisputed Посмотреть сообщение
Если вам не нужно наследоваться от шаред пойнтера - просто не делайте этого
Что? Вы хоть тему прочитайте((((( Пожалуйста))
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
27.04.2017, 12:00 9
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
если в проекте на уровне кодинг стайла будет запрещено использовать стандартные умные указатели - всё же норм будет?
Можно конечно, но стоит помнить про закон Мёрфи. И видимость что "всё хорошо" может оказаться хуже.

Раз уж начали обсуждать "плохие решения", то могу предложить ещё один плохой вариант - препроцессором shared_ptr менять на MySharedPtr.
1
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,736
Записей в блоге: 1
27.04.2017, 12:01 10
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
то память будет уничтожена дважды, когда умрёт родительский Node и при очистки умного указателя - хочу защитить самого себя от самого себя!
А зачем Вам тогда умный указатель,
если там и так есть счетчик ссылок?
1
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
27.04.2017, 12:06  [ТС] 11
Цитата Сообщение от Croessmah Посмотреть сообщение
А зачем Вам тогда умный указатель,
если там и так есть счетчик ссылок?
Умные от утечки памяти, через месяц в дальнем дальнем файле определённой глубины кто-то решит наделить класс свойствами cocos2dx - всё будет работать, но падать в деструкторах при закрытии приложения без указания, где именно.
Накатал 100500 коммитов в отдельной ветке, подтянул мастер - падение в деструктор - а где не ясно. Ревью 100500 коммитов? Там всё норм. Ревью 100500 коммитов новых в мастере - и там всё норм "вроде бы", а вот вместе падение
0
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
27.04.2017, 12:07 12
rikimaru2013,
У вас в примере идет наследование от шаред пойнтера которое вы как я понял хотите запретить в определенных условиях. Отвечая на вопрос "что" я говорю, что просто не наследуйтесь/не создавайте шаред там где это не нужно
Вот и все
0
Форумчанин
Эксперт CЭксперт С++
8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
27.04.2017, 12:56 13
Undisputed, он не хочет запретить наследование, он хочет запретить использование shared_ptr для классов, у которых уже есть счётчик. Наследование тут как пример решения данной проблемы.
1
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
27.04.2017, 13:08 14
MrGluck,
Ну заголовок во всяком случае о наследовании...

ИМХО запретить делать глупости не получится, всегда можно написать код который будет делать что-то не хорошее
Нормальное решение в таком случае это не подпускать сомнительных разработчиков к проекту а не явные моменты хорошо документировать в том же readme или где нибудь еще.

Если слишком уж болит голова относительно одного конкретного случая, можно попробовать пересмотреть архитектуру что бы исключить наболевшую проблему.
0
1550 / 875 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
27.04.2017, 13:57 15
rikimaru2013, Почему-то никто главного не сказал. Мешать разные системы автоматического управления памятью - плохая идея. shared_ptr тоже считает ссылки, просто счетчики разные в этом и проблема.
Не знаю, как там в cocos-е, но обычно если используется подсчет ссылок - деструктор должен быть protected (см. систему фасетов, например, а во всяких С# и прочих java просто нет delete, хоть реализация разная, смысл один - не дать удалить объект вручную). Тогда создать shared_ptr от класса с подсчетом ссылок просто не получится. Кроме того, при создании объекта обычно можно указать начальное значение счетчика ссылок и предотвратить его автоматическое удаление. Но лучше, все-таки, Использовать штатные средства движка (наверняка есть аналог shared_ptr в движке, в конце концов, как-то же объекты друг на друга ссылаются), тогда проблема исчезнет сама собой.
1
27.04.2017, 13:57
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
27.04.2017, 13:57
Помогаю со студенческими работами здесь

Разработать класс SpecSpec, являющийся наследником класса Spec (специальность)
Разработать класс SpecSpec, являющийся наследником класса Spec (специальность), добавив следующие...

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

Запрет определенного устройства
Как средствами C# можно запретить использование определенного устройства (например определенной...

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


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru