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

question-closed Kopiowanie głębokie obiektu ( wykonywanie kopii inteligentnego wslaźnika std::unique_ptr )

Object Storage Arubacloud
0 głosów
402 wizyt
pytanie zadane 31 marca 2019 w C i C++ przez Jakub 0 Pasjonat (23,120 p.)
zamknięte 3 kwietnia 2019 przez Jakub 0

Witam, początkowo miałem taki kod:

//-----------------------------------------------------------------------------------------------

	sf::Vector2f windowSize = window.mapPixelToCoords(sf::Vector2i(window.getSize().x, window.getSize().y));

	int numberOfEntities = 80;
	sf::Vector2f entityGenerationPoint = windowSize / 2.f; 
	float entitySeparationDistance = 30.f;
	float entitiesSpeed = 100.f;
	float entitiesNeighborhoodZone = 300.f;
	float timeToStartFlocking = 1.f;

	std::list<Entity> mainFlockingEntityList;
	for (int i = 0; i < numberOfEntities; ++i) {
		mainFlockingEntityList.emplace_back(std::make_unique<ClassicFishShape>(
			ClassicFishShape(sf::Vector2f(20.f, 30.f), std::string("fish.png"), SMALL_FISH)), AdditionalMatch::getRandomFloatValue(1.f, 360.f),
			entitySeparationDistance, i, entityGenerationPoint);
		mainFlockingEntityList.back().setObstacleBehavioursInfo(FlockingObstacle(100.f, 100.f, mainFlockingEntityList.back().getPosition()));
		mainFlockingEntityList.back().setMagnetBehavioursInfo(FlockingMagnet(100.f, 30.f, mainFlockingEntityList.back().getPosition()));
	}

auto mainFlock = std::make_unique<Flock>(mainFlockingEntityList, entitiesSpeed, entitiesNeighborhoodZone, windowSize, timeToStartFlocking, FlockingAlgorithm::FlockingBehaviourParameters{});

Wiem że tego jest dużo, myślę że nawet nie ma sensu objaśniać co ja tu robię ( po prostu tworzę obiekt o nazwie mainFlock ).Tak naprawdę znaczenie ma tylko to wywołanie:

	mainFlockingEntityList.emplace_back(std::make_unique<ClassicFishShape>( ClassicFishShape(sf::Vector2f(20.f, 30.f), std::string("fish.png"), SMALL_FISH)), AdditionalMatch::getRandomFloatValue(1.f, 360.f), entitySeparationDistance, i, entityGenerationPoint);

Korzystam w tym momencie z kontenera std::list i wywołuje metodę emplace_back, tak wygląda konstruktor klasy dodawanego do listy obiektu:

Entity::Entity(std::unique_ptr<EntityShape> entityShape, float angle, float separationSquareRootZone, int ID, sf::Vector2f position)
		: m_SeparationCubedZone(std::pow(separationSquareRootZone, 2)), m_ID(ID), m_eventStaff(nullptr) {

		angle *= AdditionalMatch::DEGREES_TO_RADIANS;
		m_velocity = sf::Vector2f(std::cos(angle), std::sin(angle));
		m_entityShape = std::move(entityShape);
		m_entityShape->setPosition(position);
	}

konstruktor kopiujący jest tu usunięty:

Entity(const Entity& entity) = delete;

Myślę że ważna jest ta linijka:

m_entityShape = std::move(entityShape);

pamięć przydzielam w wywołaniu konstruktora a tu tylko przenoszę wskaźnik.

Wszystko tu działa bez zarzutów. Koszmar się zaczął kiedy zamieniłem wszędzie kontener std::list na std::vector. Pojawił się błąd:

Z tego "ciągu znaków" zrozumiałem tyle że brakuje mi konstruktora kopiującego, nie mam pojęcia czemu wywołanie emplace_back dla std::list go nie wymaga a dla std::vector już tak, ale mi zostało tylko się podporządkować do wymagań kontenerów STL... 

Więc dodałem konstruktor kopiujący:

Entity::Entity(Entity& entity)
		: m_SeparationCubedZone(entity.m_SeparationCubedZone), m_ID(entity.m_ID), m_eventStaff(nullptr){
		m_velocity = entity.m_velocity;
                m_entityShape = std::make_unique<???>(*entity.m_entityShape); 
              
	}

Pewnie pytacie się czemu w miejsce nawiasów ostrych dałem pytajniki, to jest właśnie główny mój problem. Nie wiem co mam tu dać.

Jak zerkniemy do zwykłego konstruktora to widać:

std::unique_ptr<EntityShape> entityShape

EntityShape to klasa bazowa, jak widać na początku, może ona wskazywać na dowolną klasę pochodną:

mainFlockingEntityList.emplace_back(std::make_unique<ClassicFishShape>(...),...); 

podczas wywołania konstruktora podaję jaki typ klasy pochodnej chcę stworzyć.

Wracając do tego momentu:

m_entityShape = std::make_unique<???>(*entity.m_entityShape); 

skąd ja mam wiedzieć na jaki typ klasy pochodnej wcześniej wskazywał entity.m_entityShape? W nawiasach muszę podać typ żeby dokonać kopii, a ja go nie znam ( wiem tylko tyle że sam wskaźnik jest typu klasy bazowej... ). Próbowałem jakoś to tak rozegrać:

m_entity = std::make_unique<decltype(entity.m_entity)>(*entity.m_entity);

Ale po pierwsze nie wydaje mi się to poprawnym rozwiązaniem, a po drugie powoduje to masę błędów. Nie mam zielonego pojęcia jak mam to zrobić :(

Z góry bardzo dziękuję, jeśli czegoś nie rozumiecie a chcecie pomóc to pytajcie ;)

Tu jest cały kod: https://github.com/Jakub1010/Flocking-Algorithm-Project

tyle że wcześniejszy, ten na listach co jeszcze działa poprawnie. Najważniejsze są tam pliki Flocking.h, Flocking.cpp i main.cpp.

 

komentarz zamknięcia: problem rozwiązany.
1
komentarz 31 marca 2019 przez mokrowski Mędrzec (155,460 p.)

BTW.

https://pl.wikipedia.org/wiki/Prawo_Demeter

np.

mainFlockingEntityList.back().setMagnetBehavioursInfo(FlockingMagnet(100.f, 30.f, mainFlockingEntityList.back().getPosition())

 

komentarz 1 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)
tzn? Mógłbyś rozszerzyć? Z góry dzięki.
1
komentarz 2 kwietnia 2019 przez mokrowski Mędrzec (155,460 p.)

Dość proste. Jeśli pytasz obiekt w funkcji o obiekt który zwraca a na nim wykonujesz operację która zwraca inny obiekt, który posiada metodę która zwraca ...  to masz takie "zapuszczenie korzeni" w aplikacji że będzie Ci to bardzo niewygodnie rozplątywać.

Nieco humorystycznie:

if(ciocia.zapytajWójka("jak załatwić pompkę").załatwZzamianąNa(staryRower).pompuj(kołoWózka).zmierzSiłę() < 20Kg) {
    //... 
}

Zaczynasz od Ciotki a kończysz na kilogramach posiadając zbędną wiedzę co się dzieje po drodze. Zbędną z punktu widzenia kodu w którym teraz jesteś.

Poza tym konieczność kopiowania std::unique_ptr świadczyć może o nieadekwatnym wyborze środków (tu wskaźnika) do zadania.

komentarz 3 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)

Dziękuje za objaśnienie :) teraz zamieniłem zapis:

mainFlockingEntityList.back().setMagnetBehavioursInfo(FlockingMagnet(100.f, 30.f, mainFlockingEntityList.back().getPosition())

na:
 

mainFlockingEntityList.back().setObstacleBehavioursInfo(100.f,100.f);
mainFlockingEntityList.back().setMagnetBehavioursInfo(100.f,30.f);

Teraz odpowiednia metoda sama bierze odpowiedzialność za ustawianie tego.

1 odpowiedź

0 głosów
odpowiedź 31 marca 2019 przez j23 Mędrzec (194,920 p.)
wybrane 31 marca 2019 przez Jakub 0
 
Najlepsza

Dodaj do EntityShape wirtualną metodę tworzącą kopie obiektu (zaimplementowaną oczywiście po stronie klas pochodnych).

komentarz 1 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)

@j23

Tak dla informacji to już zastosowałem ten sposób i wszystko jest ok, tylko muszę coś zoptymalizować bo konstruktor dla każdego obiektu z jakiegoś powodu wykonuje się po kilka razy a sam proces tworzenia 100 obiektów typu Entity trwa jakieś 5 sekund...

W moim kodzie zaczynam się jednak totalnie gubić :/ Przykładowo kiedy już zastosowałem ten pomysł to przez godzinę szukałem błędu bo program wysypywał się 2 sekundy po uruchomieniu, okazało się że dodałem wywołanie metody w celu przydzielenia pamięci a nadal nie usunąłem z listy inicjalizacyjnej konstruktora pewnego błędnego przeniesienia ( wywołania std::move() ). Potem znowu nic mi się nie wyświetlało, okazało się że dałem funkcje rysującą w komentarz ;), pozatym cały kod jest fatalny. Za każdym razem jak piszę nowy projekt to przysięgam sobie że wszystko będzie miało ręce i nogi, a potem znowu piszę dziadostwo. A edycja struktury programu nie wchodzi w grę bo wymaga to zbyt dużej ilości zmian, już lepiej by było napisać coś od nowa... Nie wiem jak ludzie piszą duże projekty, skąd niby wiedzą w jaką stronę pójdzie program. U mnie jest ten problem że to miał być prosty algorytm a zabrałem się za zrobienie z tego biblioteki.

Dobra... trochę wyżaliłem się :) Jeszce raz dzięki i pozdrawiam serdecznie.

1
komentarz 2 kwietnia 2019 przez j23 Mędrzec (194,920 p.)
Zrób commita, się zobaczy.
komentarz 3 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)
https://github.com/Jakub1010/Flocking-Algorithm-Project

Już uaktualniłem, oczywiście zaznaczam że najważniejsze są pliki Flocking .h/.cpp. Reszta to tylko testowanie zawartych tam klas.
komentarz 3 kwietnia 2019 przez j23 Mędrzec (194,920 p.)
Wszystko wygląda ok, ale nie można wykluczyć, że czegoś nie zauważyłem. Czasy poprawiają się, gdy zmienisz vectora na listę?
komentarz 3 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)
Tak, tzn. płynność pozostaje taka sama ale kiedy zastosuje wektor to wszystko dużej się ładuje. Pewnie dlatego że po pierwsze dla niego wywoływany jest konstruktor kopiujący a on wywołuje jeszcze inne pomocnicze metody a po drugie chyba generalnie dla listy dodawanie i usuwanie nowych elementów trwa krócej. Udało mi się jednak ten czas czekania na początku nieco zminimalizować. Zamieniłem listę na wektor bo może się kiedyś przydać dostęp swobodny...
komentarz 3 kwietnia 2019 przez j23 Mędrzec (194,920 p.)

Dodaj może też do Entity konstruktor przenoszący, bo jeśli to tylko kwestia kontenera, to prawdopodobnie kopiowanie i usuwanie nadmiernie zabiera czas.

komentarz 3 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)
Dobra myśl. Dopiero o przenoszeniu czytałem w książce i jeszcze nie pomyślałem żeby to zastosować. Dzięki wielkie za pomoc.
komentarz 4 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)
edycja 4 kwietnia 2019 przez Jakub 0

@j23

Wiem że pytanie jest zamknięte, ale muszę jeszcze raz poprosić o pomoc bo czegoś takiego jeszcze nie widziałem... oto efekt uruchomienia programu po dodaniu konstruktora przenoszącego:

Jak widać konstruktory są wybierane tak jakby losowo ( a jak nie to na pewno w dużych ilościach ). Oto one:

Entity::Entity(std::unique_ptr<EntityShape> entityShape, float angle, float separationSquareRootZone, int ID, sf::Vector2f position)
		: m_SeparationCubedZone(std::pow(separationSquareRootZone, 2)), m_ID(ID), m_eventStaff(nullptr) {

		angle *= AdditionalMatch::DEGREES_TO_RADIANS;
		m_velocity = sf::Vector2f(std::cos(angle), std::sin(angle));
		m_entityShape = std::move(entityShape);
		m_entityShape->setPosition(position);
		std::cout << "Entity(...)\n";
	}

	///-------------------------------------------------------------------------

	Entity::Entity(const Entity& entity)
		: m_SeparationCubedZone(entity.m_SeparationCubedZone), m_ID(entity.m_ID), m_eventStaff(nullptr), m_entityShape(std::move(entity.m_entityShape->copy())) {
		m_velocity = entity.m_velocity;
		m_entityShape->setPosition(entity.m_entityShape->getPosition());
		std::cout << "Entity(const Entity& entity)\n";
	}

	///-------------------------------------------------------------------------

	Entity::Entity(Entity&& entity)
		: m_SeparationCubedZone(entity.m_SeparationCubedZone), m_ID(entity.m_ID), m_eventStaff(nullptr) {
		m_velocity = entity.m_velocity;
		auto pos = entity.m_entityShape->getPosition();
		m_entityShape = std::move(entity.m_entityShape);
		m_entityShape->setPosition(pos);
		std::cout << "Entity(Entity&& entity)\n";
	}

W main() nic się nie zmieniło, jest wszystko tak jak wcześniej. Dodałem tylko ten konstruktor przenoszący jak widać.

Zdaje sobie sprawę że teoretycznie ja lepiej wiem jak jest zbudowany mój program, nie potrafię jednak kompletnie zrozumieć skąd wynika takie a nie inne wywoływanie konstruktorów.

dla int numberOfEntities = 80 :

Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(const Entity& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)
Entity(...)
Entity(Entity&& entity)

Przepraszam za taki narzut pytań, ale dopiero poznałem i zacząłem stosować inteligentne wskaźniki oraz sygnaturę przeniesienia, więc jeszcze nie wiele z tego rozumiem, często się w tym gubię i popełniam błędy...

 

1
komentarz 4 kwietnia 2019 przez j23 Mędrzec (194,920 p.)
Entity::Entity(Entity&& entity)
		: m_SeparationCubedZone(entity.m_SeparationCubedZone)
		, m_ID(entity.m_ID)
		, m_eventStaff(nullptr) 
{
	m_velocity = entity.m_velocity;
	m_entityShape = std::move(entity.m_entityShape);
	std::cout << "Entity(Entity&& entity)\n";
}

Ustawiałeś pozycję przed przeniesieniem wskaźnika. Stąd wyjątek ;) Nie wiem, po co wywołujesz setPosition na obiekcie, który jest przenoszony.

komentarz 4 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)

Nie wiem, po co wywołujesz setPosition na obiekcie, który jest przenoszony.

Sam do końca nie wiem, bez tego pozycja sama się nie ustawi. Wydaje mi się że wynika to z tego że position jest składową klasy tego obiektu:

sf::RectangleShape m_fish;

Jest to już samo "dno abstrakcji" a więc klasa biblioteki SFML. Widocznie w konstruktorze kopiującym tej klasy nie zaimplementowano kopiowania pozycji obiektu. Innej opcji raczej nie ma...

Generalnie to uaktualniłem pytanie/komentarz bo już sam zdałem sobie sprawę z tego co zawaliłem. Jak byś mógł jeszcze raz zerknąć ;) Z góry dziękuje wink

komentarz 4 kwietnia 2019 przez j23 Mędrzec (194,920 p.)

Sam do końca nie wiem, bez tego pozycja sama się nie ustawi.

Jak nie ustawi, skoro przenosisz na własność wskaźnik na ten obiekt do innej klasy?

komentarz 4 kwietnia 2019 przez j23 Mędrzec (194,920 p.)
mainFlockingEntityList.push_back(Entity(....));

Użyj emplace_back.

Flock::Flock(std::vector<Entity>& entities, ...)
: ..., m_entities(std::move(entities)),

entities powinieneś zrobić r-referencją (teraz trochę to bałamutne).

 

komentarz 4 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)

W sumie to problem był w tym że kopiowania pozycji nie dodałem od konstruktora kopiującego klasy EntityShape:

ClassicFishShape(const ClassicFishShape& obj)
		: ClassicFishShape(obj.m_fish.getSize(), obj.m_textureLocation, obj.m_flockingObjectType) {
		m_fish.setPosition(obj.getPosition());
	}

Teraz już to załatwiłem w tamtym miejscu i w tych konstruktorach mogę to pominąć, co nie zmienia faktu że obiekt typu sf::RectangleShape sam tego za mnie nie zrobi.

Najgorsze jest to że kiedy jeden z konstruktorów ( tych trzech klasy Entity ) celowo zepsułem ( nie kopiowałem obiektu m_entityShape ) to było tylko o część obiektów ( tych ryb :) ) mniej. Tak jakby za każdym razem rzeczywiście był wykorzystywany losowo inny konstruktor...

komentarz 4 kwietnia 2019 przez Jakub 0 Pasjonat (23,120 p.)

@j23

Początkowo miałem emplace_back, widocznie zastąpiłem to push_back'iem poszukując błędu i zapomniałem zmienić z powrotem.

Tak dla informacji, teraz wywołuje mi się dla Entity tylko konstruktor zwykły i kopiujący ( bez przenoszącego ). W sumie to nwm do końca dlaczego.

Musiałem też zamienić dodatkowo:

auto mainFlock = std::make_unique<Flock>(mainFlockingEntityList, entitiesSpeed, entitiesNeighborhoodZone, displayAreaSize, timeToStartFlocking, FlockingAlgorithm::FlockingBehaviourParameters{});

na:

auto mainFlock = std::make_unique<Flock>(std::move(mainFlockingEntityList), entitiesSpeed, entitiesNeighborhoodZone, displayAreaSize, timeToStartFlocking, FlockingAlgorithm::FlockingBehaviourParameters{});

Ale to raczej oczywiste.

Podobne pytania

0 głosów
1 odpowiedź 728 wizyt
pytanie zadane 30 września 2017 w Grafika i multimedia przez DODO Bywalec (2,950 p.)
0 głosów
0 odpowiedzi 216 wizyt
0 głosów
1 odpowiedź 145 wizyt
pytanie zadane 27 maja 2016 w Sieci komputerowe, internet przez Wiiiciu Obywatel (1,090 p.)

92,551 zapytań

141,393 odpowiedzi

319,522 komentarzy

61,936 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!

...