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.