firstly iam used to java and new to c++ so maybe this will looks a noob's question i will explain this and give a pseudo code and then c++ just so you can understand me
i have a player class which inherit from gameobject and a handler class which update all the game objects(stored in vector) and render them i have a function to add objects but i get errors every time (i work with SDL2 if this gonna help)
pseudo code:
///some class
handler hand = new handler();
gameObject pla = new player();
hand.addObject(pla); ----> here
/// handler class
vector objects;
void addObjects(gameObject object)
{
objects.push(object); ------> specially here
}
C++ code
/// game class
handler hand = new handler();
gameobject* pla = new player();
hand->addobject(pla);
/// handler class
vector objects;
void addobject(gameobject* object)
{
objects.push_back(object); -----> here
}
i have searched for a week and nothing i used unique_ptr but nothing every time new error some times std::bad_alloc sometimes objects has been deleted
i am confused please guide me to the right way to do this
thank you
Answer
Your crashes is mostly because of improper handling of the object's ownership.
When you add something to a collection, you should clearly understand who's owning the object. Is that handler owns the added objects now, and may delete those when time has come? Or is that handler only references the objects, and there's some other subsystem that will destroy the objects? Get clear with ownership first, because implementation will differ.
Assigning unique_ptr
to a collection assumes ownership is transferred to that collection. There's no other way to push_back
the unique_ptr
into a vector
. There can't be multiple copies of the same unique_ptr
. Well, technically you could construct multiple unique_ptr
from the very same raw pointer, but that's a big no-no.
In case your handler
will own the objects, the next example is possible:
#include
#include
using std::vector;
using std::unique_ptr;
using std::move;
/// gameobjec base class
class gameobject
{
public:
virtual ~gameobject() {};
};
/// player class
class player: public gameobject
{
public:
float* some_data;
player(int map_size)
{
some_data = new float[map_size];
}
~player()
{
delete[] some_data;
}
};
/// handler class
class handler
{
public:
vector objects;
vector > objects_auto;
void addobject(gameobject* object)
{
objects.push_back(object);
}
void addobject(unique_ptr& object)
{
objects_auto.push_back(move(object));
}
void add_raw_to_auto(gameobject* object)
{
objects_auto.push_back(unique_ptr(object));
}
~handler()
{
// objects behind raw pointers must be explicitly deleted
for(auto obj: objects)
delete obj;
// nothing needs to be done about unique_ptr containers
}
};
int main()
{
handler* hand = new handler();
for(int i=0; i<100; ++i)
{
// add raw pointer to a collection of raw pointers
gameobject* pla = new player(i);
hand->addobject(pla);
// add unique_ptr to a collection of unique_ptr
unique_ptr pla_auto(new player(i*2));
hand->addobject(pla_auto);
// add raw pointer to a collection of unique ptr
gameobject* pla_raw = new player(i);
hand->add_raw_to_auto(pla_raw);
}
delete hand;
}
Since in handler
you're storing the pointer to a base class, you should make virtual destructor there, so the collections of pointers to different objects inherited from that base class will be properly destroyed. A memory leaks are possible if the base class' destructor isn't virtual.
No comments:
Post a Comment