utilizarea corectă a std :: vector.push_back () cu un tip definit de utilizator

Am primit defecte de segmentare (cred) cu metoda curentă de vector.push_back ().

Iată câteva exemple de cod:

Deci am clasa mea Zombie

class Zombie
{
    public:
       Zombie();
       ~Zombie();

       SDL_Surface* image;

       SDL_Rect box;

       bool dead;

   protected:

   private:
      //gets random coordinates around the screen
       SDL_Rect get_zombie_rect();
 };

constructorul fiind:

Zombie::Zombie()
   :
   dead(false),
   image(load_image("Player.png")),
   box(get_zombie_rect())
{

}

și Zombie are o clasă de handler pentru a gestiona vectorul cu o funcție numită create_new_zombie (). (aici este problema)

void Zombie_Manager::create_new_zombie()
{
   Zombie newZombie;
   zombies.push_back(newZombie);
}

Este aceasta metoda corecta de a adauga un element unui vector?

Sunt capabil să obțin o versiune de lucru cu ajutorul indicatoarelor, dar trebuie să existe o modalitate mai ușoară și mai corectă de a realiza acest lucru, nu?

De ce primesc o eroare dacă vectorul std :: vector.push_back() copiază noile sale elemente? Am greșit în asumarea asta?

0
duplicat posibil din Ce este regula celor trei?
adăugat autor fredoverflow, sursa
Sper că îți dai seama că image este gunoi neinitializat.
adăugat autor John Dibling, sursa
@Chris: Cred că atunci când cealaltă întrebare este o întrebare frecventă.
adăugat autor ildjarn, sursa
Nu cred că fiecare întrebare la care se răspunde răspunsul la o altă întrebare este un duplicat, nu-i așa?
adăugat autor Chris A., sursa

1 răspunsuri

You need to implement a copy constructor and an assignment operator.

zombies.push_back(newZombie); pushes a copy of newZombie in the vector. When the method enters, the original newZombie is destroyed. And I'm willing to bet that in ~Zombie() you call delete image;.

Deoarece nu aveți un constructor corect de copiere și un operator de atribuire, toate copiile vor fi nevalide, deoarece vor conține pointer încurcat.

Respectați întotdeauna regula a trei - dacă trebuie să implementați un destructor, trebuie să implementați și un operator c-ctor și alocare.

0
adăugat
@ 0A0D o face, dar face o copie superficială. Pointerul image din copie indică aceeași locație ca și cea originală. Deci, atunci când cel original este distrus, pointerul din copie va fi încurcat.
adăugat autor Luchian Grigore, sursa
Și deoarece obiectul conține indicii brute, va trebui să fie o copie profundă . Sau mai bine utilizați un cod shared_ptr .
adăugat autor Mark Ransom, sursa
Având în vedere că este vorba de SDL despre care vorbim, nu cred că există un delete actual. Oricum, un indicator poticnitor este foarte probabil problema. Dacă C ++ 11 este o opțiune, aș recomanda, de asemenea, implementarea unui constructor de mișcări pentru a putea utiliza în mod eficient containerele STL (fără a recurge la stocarea indicatorilor sub nici o formă).
adăugat autor eq-, sursa