Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Воротислав
124 / 102 / 27
Регистрация: 25.02.2010
Сообщений: 451
#1

Smart pointer - C++

02.09.2015, 08:53. Просмотров 452. Ответов 6

Доброго времени суток.
Вопросы мои связаны с началом изучения умных указателей в C++ и применении в проектах.

Взял за начало обучения статью на хабре http://habrahabr.ru/post/140222/

1. В статье написано инициализация указателя
C++ (Qt)
1
2
3
int test() {
    std::shared_ptr<MyObject> p1(new MyObject);
}
То есть внутри функции. Я в проектах, в некоторых случаях использую:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
// MyClass.h
class MyClass
{
...
private:
    MyObject *obj;
}
 
// MyClass.cpp
MyClass::MyClass()
{
    obj = new MyObject();
}
И далее в тексте работаю с указателем на объект MyObject.
Вопрос в следующем, как мне в таком же стиле применить shared_ptr?
Правильно ли будет писать так:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
// MyClass.h
class MyClass
{
...
private:
    std::shared_ptr<MyObject> obj;
}
 
// MyClass.cpp
MyClass::MyClass()
{
    obj = std::shared_ptr<MyObject>(new MyObject());
}
2.
В одном из проектов необходимо использовать следующую конструкцию.
Есть класс Книга, в которой есть поля название, автор и прочее.
Есть класс Комната, в которой есть вектор, содержащий указатели на книги, находящиеся в данной комнате.
Есть управляющий класс Агент, который следит за передвижением книг.
Суть какая, при запуске Агент создает комнаты, и в дальнейшем создает книги. Затем он их должен положить в комнату. Правильно ли будет использовать в данном случае умные указатели (ибо я боюсь запутаться в указателях), и создав shard_ptr<Book> book1 (new Book ("Bukvar")); затем передать его в комнату. а при необходимости взять оттуда?

3. этот вопрос больше касается Qt, но не охото плодить темы, возможно здесь ответят.
Как Qt дружит с std::shared_ptr? Я например окошки создаю так:
C++ (Qt)
1
2
3
4
5
6
void MyWidget::on_buttonSettings_clicked()
{
   DialogSettings *set = new DialogSettings( this);
   set->exec();
   delete set;
}
Возможно ли и здесь применить shared_ptr??

Заранее благодарен.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.09.2015, 08:53
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Smart pointer (C++):

Создание Smart pointer
Здравствуйте. Я хотел бы рассказать зачем Smart pointer и чем они полезны при...

smart pointer с указателем на new[]
Как я понимаю, реализация shared_ptr boost или tr1 подразумевает, что в неё...

Thread-safe smart pointer
Нужно мне это для реализации COW механизма. В STL, насколько я понимаю,...

Shared_ptr - stored pointer, owned pointer
Зачем в shared_ptr нужен хранимый указатель, отличный от владеемого? И так в...

delete[] *pointer vs. delete pointer и утечка памяти
Здравствуйте! Есть класс &quot;умного&quot; указателя counted_ptr, который удаляет...

pointer - pointer
#include&lt;iostream&gt; #include&lt;algorithm&gt; using namespace std; int main() {...

6
rikimaru2013
C++ Game Dev
2471 / 1140 / 348
Регистрация: 30.11.2013
Сообщений: 3,709
02.09.2015, 09:09 #2
Лучший ответ Сообщение было отмечено Воротислав как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
// MyClass.h
class MyClass
{
...
private:
    std::shared_ptr<MyObject> obj;
}
 
// MyClass.cpp
MyClass::MyClass()
{
    obj.reset(new MyObject());
}
1
DrOffset
7518 / 4514 / 1097
Регистрация: 30.01.2014
Сообщений: 7,362
02.09.2015, 09:34 #3
Лучший ответ Сообщение было отмечено Воротислав как решение

Решение

Цитата Сообщение от Воротислав Посмотреть сообщение
Как Qt дружит с std::shared_ptr?
Если ты будешь указывать родителя в конструкторе создаваемого объекта, то этот родитель при своем уничтожении будет пытаться уничтожить также и свои дочерние объекты. Если дочерний объект сидит в shared_ptr, то это уничтожение останется незамеченным для него. И он будет продолжать считать, что ссылается на валидный объект.
Т.е. ситуация эквивалентна такой:
C++
1
2
3
4
5
6
7
8
{
    MyClass * obj = new MyClass();
    std::shared_ptr<MyClass> objPtr(obj);
    delete obj;
    
    objPtr->foo(); // oops
 
} // ~std::shared_ptr<MyClass>() - oops
В связи с этим использовать можно, но осторожно. Следить на временем жизни родителя, чтобы оно не закончилось раньше, чем время жизни последней копии shared_ptr, либо не указывать родителя вовсе.

Добавлено через 2 минуты
Цитата Сообщение от Воротислав Посмотреть сообщение
Возможно ли и здесь применить shared_ptr??
Конкретно в приведенном коде shared_ptr вообще-то избыточен. Достаточно сделать так:
C++
1
2
3
4
5
void MyWidget::on_buttonSettings_clicked()
{
   std::unique_ptr<DialogSettings> set(new DialogSettings(this));
   set->exec();
}
1
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
02.09.2015, 10:11 #4
Воротислав, Инициализировать лучше в списке инициализации, а не в конструкторе непосредственно.

C++
1
2
3
4
5
6
7
8
9
10
11
12
// MyClass.h
class MyClass
{
...
private:
    std::shared_ptr<MyObject> obj;
}
 
// MyClass.cpp
MyClass::MyClass() : obj(new MyObject())
{
}
Или же через make_shared.
1
Воротислав
124 / 102 / 27
Регистрация: 25.02.2010
Сообщений: 451
02.09.2015, 11:02  [ТС] #5
ForEveR, а через make_shared будет выглядеть так:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
// MyClass.h
class MyClass
{
...
private:
    std::shared_ptr<MyObject> obj;
}
 
// MyClass.cpp
MyClass::MyClass()
{
    obj = std::make_shared<MyObject>();
}
??
0
ForEveR
В астрале
Эксперт С++
7994 / 4753 / 651
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
02.09.2015, 11:03 #6
Лучший ответ Сообщение было отмечено Воротислав как решение

Решение

Воротислав, Угу. Или так же в конструкторе инициализации. Или прям в классе, если поддерживается инициализация в классе.
1
Воротислав
124 / 102 / 27
Регистрация: 25.02.2010
Сообщений: 451
02.09.2015, 11:04  [ТС] #7
Понял, пойду пробовать, учиться. Всем большое спасибо!
0
02.09.2015, 11:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.09.2015, 11:04
Привет! Вот еще темы с решениями:

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

Null pointer
void C_StringBit :: setStrBit() { char* ptr1; cout &lt;&lt; &quot;Введите строку&quot;&lt;&lt;...

Pointer. Int *
Создать функцию, которая находит максимальное значение из int *a pointer...

Invalid pointer operation
Добрый вечер. Возникает такая ошибка при выключении программы: invalid pointer...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru