Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.89/9: Рейтинг темы: голосов - 9, средняя оценка - 4.89
28 / 27 / 7
Регистрация: 11.06.2011
Сообщений: 366
1

Копирование std::unique_ptr в структуре

28.10.2014, 07:06. Показов 1695. Ответов 8
Метки нет (Все метки)

Есть структуры и vector
C++
1
2
3
4
5
6
7
8
9
10
11
12
struct myStruct {
 int a;
 int b;
 void* param;
};
 
struct sSetup {
 int x;
 int y;
}
 
std::vector<myStruct> myvector
есть, примерно, вот такой код (Пишу прям в форуме. Могут быть синтаксические ошибки):
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
void init(){
   std::unique_ptr<sSetup> setup(new sSetup());
   setup.get()->x=1;
   setup.get()->y=1;
   myvector.push_back(setup.release());
}
 
std::vector<myStruct>  getVector(){
   std::vector<myStruct> temp=myvector;
   myvector.clear();
   return temp;
}
 
void test(){
   std::vector<myStruct> temp=getVector();
   for (int i=0;i<temp.size();i++){
      std::unique_ptr<sSetup> setup(static_cast<sSetup*>(temp.at(i).param));
      std::cout << setup.get()->x << std::endl;
   }
}
 
int main(){
  init();
  test();
  return 1;
}
Код, работает. Но может это совпадение. Что происходит с умным указателем в функции getVector ?
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.10.2014, 07:06
Ответы с готовыми решениями:

Копирование объектов std::unique_ptr
привет, столкнулся с такой ситуацией, что вроде как копировать объекты std::unique_ptr запрещено,...

Использование std::unique_ptr
Есть в коде подобная конструкция, вылетает исключение на этапе очистки памяти. С чем это может быть...

Std::unique_ptr virtual метод
#include &lt;iostream&gt; #include &lt;memory&gt; class Base { public: virtual void f1(); // Virtual...

Компилятор не видит std::unique_ptr
Не создается unique_ptr int main(int argc, char *argv) { QCoreApplication a(argc, argv);...

8
С чаем беда...
Эксперт CЭксперт С++
9145 / 4664 / 1268
Регистрация: 18.10.2014
Сообщений: 10,517
28.10.2014, 08:09 2
Цитата Сообщение от admsasha Посмотреть сообщение
Что происходит с умным указателем в функции getVector ?
Никаких умных указателей, никаких 'std::unique_ptr' ни в векторе, ни в функции 'getVector' я в упор не вижу.

О чем вопрос? Где вы тут увидели "копирование std::unique_ptr в структуре"? Где вы увидели "умные указатели в функции getVector"?
0
28 / 27 / 7
Регистрация: 11.06.2011
Сообщений: 366
28.10.2014, 08:15  [ТС] 3
ой, немного не правильно написал
C++
1
2
3
4
5
6
7
void init(){
   std::unique_ptr<sSetup> setup(new sSetup());
   setup.get()->x=1;
   setup.get()->y=1;
   st.param=setup.release();         // вот так правильно
   myvector.push_back(st);
}
0
С чаем беда...
Эксперт CЭксперт С++
9145 / 4664 / 1268
Регистрация: 18.10.2014
Сообщений: 10,517
28.10.2014, 08:17 4
Цитата Сообщение от admsasha Посмотреть сообщение
ой, немного не правильно написал
И что?

По-прежнему в коде нет ни одной структуры с unique_ptr. По-прежнему функция getVector не работает ни с какими умными указателями. В вашей структуре хранится 'void *'. 'void *' - это никакой не умный указатель. Это обычный указатель, который просто копируется при копировании структуры.

Еще раз: в чем заключается вопрос?
0
28 / 27 / 7
Регистрация: 11.06.2011
Сообщений: 366
28.10.2014, 08:19  [ТС] 5
Хм...
C++
1
 std::unique_ptr<sSetup> setup(new sSetup());
Создает умный указатель, верно ?

C++
1
2
   st.param=setup.release(); 
   myvector.push_back(st);
Пишем в структуру и добавляем в вектор, так ? Или я не правильно это понимаю ?
0
С чаем беда...
Эксперт CЭксперт С++
9145 / 4664 / 1268
Регистрация: 18.10.2014
Сообщений: 10,517
28.10.2014, 08:23 6
Цитата Сообщение от admsasha Посмотреть сообщение
Создает умный указатель, верно ?
Да, верно.

Цитата Сообщение от admsasha Посмотреть сообщение
C++
1
2
st.param=setup.release(); 
myvector.push_back(st);
Пишем в структуру и добавляем в вектор, так ? Или я не правильно это понимаю ?
Правильно. Но, функция 'setup.release()' превращает умный указатель в обыкновенный "неумный" указатель. Этот "неумный" указатель типа 'void *' и хранится в вашем векторе. Дальше в своей программе вы работаете только с ним. Никаких "умных указателей" в вашем векторе нет. А умный указатель 'setup' (который стал "пустым", после вызова 'release()') уничтожается при выходе из 'init()'.

Если вы хотите хранить 'std::uniqre_ptr' в вашей структуре, то так и пишите

C++
1
2
3
4
5
struct myStruct {
 int a;
 int b;
 std::unique_ptr<sSetup> param;
};
И вот тут уже начнутся тонкости...
1
28 / 27 / 7
Регистрация: 11.06.2011
Сообщений: 366
28.10.2014, 08:40  [ТС] 7
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Правильно. Но, функция 'setup.release()' превращает умный указатель в обыкновенный "неумный" указатель. Этот "неумный" указатель типа 'void *' и хранится в вашем векторе. Дальше вы работаете только с ним.
Теперь понятно. Только теперь вопрос, как именно умный указать в эту схему пристроить ?
Простое
C++
1
st.param=setup
Не компилится.

Добавлено через 14 минут
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
std::unique_ptr<sSetup> param;
Но это не замена void*. void* создан для присвоения любого типа данных, а не только sSetup.

C++
1
2
3
4
5
6
7
void init(){
sSetup setup;
   setup.get().x=1;
   setup.get().y=1;
   st.param=(void*)setup;
   myvector.push_back(st);
}
какой срок жизни у st.param ?
0
С чаем беда...
Эксперт CЭксперт С++
9145 / 4664 / 1268
Регистрация: 18.10.2014
Сообщений: 10,517
28.10.2014, 08:42 8
Лучший ответ Сообщение было отмечено admsasha как решение

Решение

Цитата Сообщение от admsasha Посмотреть сообщение
C++
1
st.param=setup
Не компилится.
Разумеется не компилится. 'std::unique_ptr' копировать нельзя. Его можно только перемещать:

C++
1
st.param = std::move(setup);
Но я бы не советовал идти по этому пути - слишком много надо будет настраивать, аккуратно "перемещать" из одного места в другое и стараться не "потерять" по дороге.

Если уж вы хотите использовать умный указатель, то лучше было бы использовать 'std::shared_ptr'. Или он вас чем-то не устраивает?

Добавлено через 2 минуты
Цитата Сообщение от admsasha Посмотреть сообщение
какой срок жизни у st.param ?
Что именно вы имеете ввиду? Срок жизни самого указателя такой же, как и у содержащей его структуры. Но если 'st.param' объявлен как 'void *', то от его срока жизни ничего не зависит. Он не будет освобождать за вас указуемый объект. Это не умный указатель.

Что вы имели в виду под 'st.param = (void*) setup' мне не ясно. Это бессмысленно и не компилируемо.
0
:)
Эксперт С++
4769 / 3263 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
28.10.2014, 11:09 9
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
то лучше было бы использовать 'std::shared_ptr'.
А как насчет такого мнения:
Usually, try to use either scoped_ptr or unique_ptr. If you need several owners try to change the design. If you can't change the design and really need several owners, use a shared_ptr, but beware of references cycles that ought to be broken using a weak_ptr somewhere in the midst.
отсюда
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.10.2014, 11:09

Отсутствует std::unique_ptr gcc 4.8.1
всем привет , я в С++ начинающий и возникла проблема не работает std::unique_ptr версия...

Не срабатывает move конструктор std::unique_ptr
Всем привет! Битый час не пойму почему в списке захвата компилятор ругается на удаленный копирующий...

Шаблонные аргументы конструктора std::unique_ptr
Если я пишу код std::unique_ptr&lt;int, void(*)(int*)&gt; myPtr_5(new int, (int* p) {delete p; });...

Копирование объектов std::thread
В учебнике Энтони Уильямса есть простой пример класса scoped_thread, присоединяющего поток в...


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

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

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