• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Kopiowanie unique_ptr

Object Storage Arubacloud
+1 głos
299 wizyt
pytanie zadane 8 grudnia 2015 w C i C++ przez GameProgrammer Obywatel (1,140 p.)
Jak kopiować obiekt unique ptr do innych obiektów?

2 odpowiedzi

+3 głosów
odpowiedź 8 grudnia 2015 przez Radfler VIP (101,030 p.)
edycja 8 grudnia 2015 przez Radfler

W sensie? Sam typ std::unique_ptr jest niekopiowalny. Można go przenosić:

// a, b - obiekty typu std::unique_ptr<int>
a = std::move(b); // a przejmuje kontrolę nad obiektem, b jest pusty

A jeżeli chcesz "wyciągnąć" z niego wskaźnik na obiekt to użyj funkcji get:

// a - obiekt typu std::unique_ptr<int>, b - obiekt typu int*
b = a.get(); // a cały czas ma kontrolę nad obiektem, na który wskazuje

#EDIT Jeżeli zależy Ci na kopiowaniu, to użyj typu std::shared_ptr.

komentarz 8 grudnia 2015 przez GameProgrammer Obywatel (1,140 p.)
Zamieniem unique na shared, przekazuję z obieku a do b obiekt shared_ptr

b.shared = a.sharedPtr

potem z b przekazuję do c w ten sam sposób, jednak to działą tak jakby cały czas istniał jeden obiekt, i jak zmienię parametry obiektu shared w obiekcie c, to zmieni się też w a i b. A ja chcę utworzyć drugą taką samą kopię.
komentarz 8 grudnia 2015 przez Radfler VIP (101,030 p.)

Jeżeli chcesz przekopiować sam obiekt związany z std::unique_ptr/std::shared_ptr, to robisz to tak:

std::unique_ptr<int> a(new int(10));

std::unique_ptr<int> b(new int(*a)); // Kopiowanie samego obiektu
komentarz 8 grudnia 2015 przez GameProgrammer Obywatel (1,140 p.)

Prawie działa, te obiekty shared_ptr są też wskaźnikami na inne obiekty, i przy kopiowaniu kopiuje się tylko wskaźnik, a to na co on wskazywał już nie,

 


class a{}

class b : public a {}

std::shared_ptr<a> test;

test = std::shared_ptr<b>(new b());



i teraz jak chcę przekopiować test tak jak pokazałeś, to wychodzi sam wskaźnik bez tego na co wskazywał;

komentarz 8 grudnia 2015 przez Radfler VIP (101,030 p.)

Obiekt, który tworzysz w linijce 7 jest przenoszony do zmiennej test. I teraz on ma nad nim kontrolę. Poza tym test nie wskazywał przed tą instrukcją na żaden obiekt, więc niemożliwe jest przypisanie do niego (który nie istnieje) jakiejkolwiek wartości.

Ogólnie też nie rozumiem Twojego przykładu, przecież można zrobić po prostu tak:

std::shared_ptr<a> test(new b());
komentarz 8 grudnia 2015 przez GameProgrammer Obywatel (1,140 p.)

std::shared_ptr<a> test(new b());

 

i teraz ten obiekt "b" chcę przekopiować do innego obiektu typu std::shared_ptr<a>;

Teraz jak robię tak:

				effect.push_back(std::shared_ptr<Effect>(new Effect(*entity.bullet[i] -> getEffect())));

I obiekt wchodzi w update to do podstawowej metody typu Effect, a powinien do ElementalEffect.

komentarz 8 grudnia 2015 przez Radfler VIP (101,030 p.)

Rozumiem, że effect to std::vector<std::shared_ptr<Effect>>. To może tak:

1. Zamiast push_back, użyj emplace_back. Nie będziesz musiał dokonywać konwersji na std::shared_ptr:

effect.emplace_back(new Effect(*entity.bullet[i] -> getEffect()));

2. Jeżeli chcesz wywołać funkcję update z klasy ElementalEffect to utwórz obiekt tej klasy:

effect.emplace_back(new ElementalEffect(*entity.bullet[i] -> getEffect()));

3. I jeszcze pytanie: czy klasa Effect ma zdefiniowany konstruktor kopiujący? I czy masz zadeklarowaną funkcję update jako wirtualną?

komentarz 8 grudnia 2015 przez GameProgrammer Obywatel (1,140 p.)
edycja 8 grudnia 2015 przez GameProgrammer

Tak, update jest wirtualna, i Effect nie ma konstruktora kopiującego.

I tak się nie da:

effect.emplace_back(new ElementalEffect(*entity.bullet[i] -> getEffect()));

Zapewne przez brak konstruktora kopiującego, tylko jak go stworzyć żeby kopiował w poprawny sposób?

komentarz 8 grudnia 2015 przez Radfler VIP (101,030 p.)

To nie jest raczej wina konstruktora kopiującego. Powiedz mi jakiego typu jest to wyrażenie:

*entity.bullet[i] -> getEffect()

To jest Effect&, ElementalEffect& czy może coś jeszcze? Bo konstruktor kopiujący klasy ElementalEffect przyjmuje argument typy const ElementalEffect&. Spróbuj użyć operatora dynamic_cast<> przy tworzeniu obiektu:

dynamic_cast<ElementalEffect&>(*entity.bullet[i] -> getEffect())
komentarz 8 grudnia 2015 przez GameProgrammer Obywatel (1,140 p.)
effect.push_back(dynamic_cast<ElementalEffect&>(*entity.bullet[i] -> getEffect()));

Też nie działa.

Co do pytania:

std::shared_ptr <Effect> Bullet::getEffect()
{
	return effect;
}

 

komentarz 8 grudnia 2015 przez Radfler VIP (101,030 p.)

Użyj emplace_back (C++11), a nie push_back. Jeżeli będą jeszcze jakieś błędy, to wrzuć je na pastebin i podeślij mi link. Może wtedy odkryję co jest nie tak.

komentarz 8 grudnia 2015 przez GameProgrammer Obywatel (1,140 p.)

Error    20    error C2664: 'std::shared_ptr<_Ty>::shared_ptr(std::nullptr_t)' : cannot convert parameter 1 from 'ElementalEffect' to 'std::nullptr_t'

			effect.emplace_back(dynamic_cast<ElementalEffect&>(*entity.bullet[i] -> getEffect()));

 

komentarz 8 grudnia 2015 przez Radfler VIP (101,030 p.)

Z tego co wcześniej napisałeś, to do wektora effect chcesz wpisać nowy obiekt. Spróbuj jeszcze tak:

effect.emplace_back(new ElemntalEffect(dynamic_cast<ElementalEffect&>(*entity.bullet[i]->getEffect())));

Jak to nie zadziała, to chodź na czat...

komentarz 8 grudnia 2015 przez GameProgrammer Obywatel (1,140 p.)
Działa wszystko poprawnie, dzięki :)
komentarz 8 grudnia 2015 przez Radfler VIP (101,030 p.)
To dopiero było zadanie xd
0 głosów
odpowiedź 8 grudnia 2015 przez Mikrokontroler xD Stary wyjadacz (13,500 p.)

Podobne pytania

0 głosów
1 odpowiedź 423 wizyt
+1 głos
1 odpowiedź 239 wizyt
pytanie zadane 17 października 2015 w C i C++ przez GameProgrammer Obywatel (1,140 p.)
0 głosów
3 odpowiedzi 327 wizyt
pytanie zadane 17 października 2015 w C i C++ przez GameProgrammer Obywatel (1,140 p.)

92,576 zapytań

141,426 odpowiedzi

319,652 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...