Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Воротислав
124 / 102 / 27
Регистрация: 25.02.2010
Сообщений: 448
#1

Smart pointer - C++

02.09.2015, 08:53. Просмотров 405. Ответов 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 с указателем на new[] - C++
Как я понимаю, реализация shared_ptr boost или tr1 подразумевает, что в неё будет передан одиночный объект, который будет удален через...

Создание Smart pointer - C++
Здравствуйте. Я хотел бы рассказать зачем Smart pointer и чем они полезны при разработке. Smart pointer — это объекты, которые работают...

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

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

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

pointer - pointer - C++
#include&lt;iostream&gt; #include&lt;algorithm&gt; using namespace std; int main() { int arr = {8,4,6,15,36,78,9,10}; int...

6
rikimaru2013
C++ Game Dev
2468 / 1137 / 240
Регистрация: 30.11.2013
Сообщений: 3,700
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
7506 / 4502 / 1023
Регистрация: 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
В астрале
Эксперт С++
7988 / 4747 / 321
Регистрация: 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
Сообщений: 448
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
В астрале
Эксперт С++
7988 / 4747 / 321
Регистрация: 24.06.2010
Сообщений: 10,547
Завершенные тесты: 3
02.09.2015, 11:03 #6
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Воротислав, Угу. Или так же в конструкторе инициализации. Или прям в классе, если поддерживается инициализация в классе.
1
Воротислав
124 / 102 / 27
Регистрация: 25.02.2010
Сообщений: 448
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* - C++
Создать программу, которая перемещает каждую букву на заданное количество по алфавиту. Ввод: char *slovo, int chislo. (например, &quot;zima&quot;,...

Null pointer - C++
void C_StringBit :: setStrBit() { char* ptr1; cout &lt;&lt; &quot;Введите строку&quot;&lt;&lt; endl; cin &gt;&gt; ptr1; lengthBit = strlen(ptr1); ...

Pointer. Int * - C++
Создать функцию, которая находит максимальное значение из int *a pointer (подсказка: используйте *a pointer как динамичный массив, также...

invalid pointer operation - C++
for (global_index1 = 0; global_index1 &lt; t-&gt;dir_list-&gt;Count; global_index1++) { for (int j = 0; j &lt;...


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

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

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