331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
1

Правильное использование умных указателей, как членов класса

11.01.2017, 01:31. Показов 1799. Ответов 9
Метки нет (Все метки)

Допустим у нас есть класс Node, объекты которого могут хранить вложенные Node, как правильнее объявлять конструктор?
Так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Node
{
public:
    std::shared_ptr<Node> child;
    Node()
    {
 
    }
    Node(Node *child)
        :child(child)
    {
 
    }
};
Или так?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Node
{
public:
    std::shared_ptr<Node> child;
    Node()
    {
 
    }
    Node(std::shared_ptr<Node> const &child)
        :child(child)
    {
 
    }
};
Первый вариант удобнее вызывать, но нет ли в нём каких-нибудь подводных камней?
И если я правильно понял, здесь лучше использовать unique_ptr. Как его передавать через конструктор? Следующий вариант
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Node
{
public:
    std::unique_ptr<Node> child;
    Node()
    {
 
    }
    Node(std::unique_ptr<Node> const &child)
        :child(child)
    {
 
    }
};
не компилится
C++
1
2
3
main.cpp:31: error: use of deleted function 'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Node; _Dp = std::default_delete<Node>]'
         :child(child)
                     ^
Спасибо
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.01.2017, 01:31
Ответы с готовыми решениями:

Использование умных указателей
В каких случаях вы используете умные указатели, а в каких обычные?

Использование умных указателей
Всем привет! Недавно наконец попробовал использовать умные указатели и мне понравилось, но...

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

Правильное использование указателей на процедуры без параметров
с указателем на вложенные процедуры переменные главной процедуры читаются не верно! Как заставить...

9
Don't worry, be happy
17780 / 10544 / 2035
Регистрация: 27.09.2012
Сообщений: 26,514
Записей в блоге: 1
11.01.2017, 01:37 2
Цитата Сообщение от DevAlone Посмотреть сообщение
не компилится
unique_ptr - единоличный владелец.
Так что копировать его нельзя,
а вот перемещать можно.
1
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
11.01.2017, 01:45  [ТС] 3
Цитата Сообщение от Croessmah Посмотреть сообщение
unique_ptr - единоличный владелец.
Так что копировать его нельзя,
а вот перемещать можно.
что-то вроде?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Node
{
public:
    std::unique_ptr<Node> child;
    Node()
    {
 
    }
    Node(std::unique_ptr<Node> child)
        : child(std::move(child))
    {
 
    }
};
0
Эксперт по математике/физикеЭксперт С++
2001 / 1332 / 379
Регистрация: 16.05.2013
Сообщений: 3,450
Записей в блоге: 6
11.01.2017, 07:45 4
DevAlone, что-то вроде:
C++
1
2
3
4
5
6
7
8
9
10
class Node {
    std::unique_ptr<Node> child;
public:
    Node()
    {}
    Node(std::unique_ptr<Node>&& child)
        : child(std::move(child))
    {}
    Node(const Node&) = delete;
};
1
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
11.01.2017, 17:53  [ТС] 5
Спасибо, а про первый вопрос, какой конструктор правильнее?
C++
1
2
Node(Node *child)
        :child(child)
или
C++
1
2
Node(std::shared_ptr<Node> const &child)
        :child(child)
0
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
11.01.2017, 18:29 6
Цитата Сообщение от DevAlone Посмотреть сообщение
Спасибо, а про первый вопрос, какой конструктор правильнее?
оба не правильные.
1
Форумчанин
Эксперт CЭксперт С++
8193 / 5043 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453
11.01.2017, 18:54 7
Если есть вероятность кольцевой зависимости, то правильно использовать std::weak_ptr.
1
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
11.01.2017, 22:27  [ТС] 8
Цитата Сообщение от hoggy Посмотреть сообщение
оба не правильные.
а какой правильный и почему?
0
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
11.01.2017, 22:48 9
Цитата Сообщение от hoggy Посмотреть сообщение
оба не правильные.
а что вы имеете ввиду?
1
Эксперт С++
8718 / 4299 / 957
Регистрация: 15.11.2014
Сообщений: 9,743
12.01.2017, 01:20 10
Цитата Сообщение от DevAlone Посмотреть сообщение
а какой правильный и почему?
в обоих случаях нарушается инвариант Node
не сложно смоделировать ситуацию,
при которой будет поломка.

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

так же, ваш код допускает,
что в качестве ребенка может оказаться сам родитель.
во втором случае это легко может привести к циклической зависимости.

Добавлено через 3 минуты
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
а что вы имеете ввиду?
что бы смоделировать граф,
нужно велосипедить сборку мусора.

в деревья контролируют создание ребенка,
и держат его по значению
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.01.2017, 01:20
Помогаю со студенческими работами здесь

Как правильней переписать код с использованием умных указателей?
Всем привет. Есть код: TImage *im1 = new TImage(NULL); TImage *im2 = new TImage(NULL);...

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

Использование динамических массивов как членов класса
Здравствуйте, подскажите как правильно создать динамические массивы для данных класса stud. Я...

Использование char строк как членов класса
Изначально всё получалось, смог вывести как надо возраст ( int age ) Но застрял на выводе имени (...

Подсчет умных указателей
Здравствуйте! Столкнулся с проблемой реализации умных указателей . Совсем не выходит написать...

Приведение типов умных указателей
Добрый день. Реализовал простенький умный указатель с подсчетом ссылок. template&lt;typename...


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru