Delete and remove a pointer from a list - c++

I have this code (its a smol version of the code that replicates the error) and it gives a some kind of error with memory. idk just pls help me fix it. It deletes the object so there remains just the nullptr. Idk why but it doesn't want to remove the pointer from the list.
#include <iostream>
#include <list>
// casual include
here i create a class thats the base for all of my other classes
class Object // a virtual class
{
public:
bool needs_delete = false;
virtual void tick() {}
virtual void render() {}
};
a player class that inherits from the Object class i created earlier
class Player : public Object
{
public:
float x, y; // <-- just look at da code dont read dis
Player(float x, float y) : // i initialize the "x" & "y" with the x & y the user has set in the constructor
x(x), y(y)
{}
void tick() override // just look at the code
{
x++;
if (x > 10000)
{
needs_delete = true;
}
}
void render() override // just look at the code
{
// nothing...
}
};
just the main function. at this point im just writing text because stackoverflow wont let me post this piece of constant depression. pls help :)
int main()
{
std::list<Object*>* myObjs = new std::list<Object*>; // a list that will contain the objects
for (int i = 0; i < 1000; i++) // i create 1k player just for testing
{
myObjs->push_back(new Player(i, 0));
}
while (true)
{
if (myObjs->size() == 0) // if there are no objects i just break out of the loop
break;
for (Object* obj : *myObjs) // update the objects
{
obj->tick();
obj->render();
// some other stuff
}
// DA PART I HAVE NO IDEA HOW TO DO
// pls help cuz i suck
for (Object* obj : *myObjs) // help pls :)
{
// baisicly here i want to delete the object and remove it from the list
if (obj->needs_delete)
{
std::cout << "deleted object\n";
delete obj;
myObjs->remove(obj);
}
}
}
}

What about:
myObjs->remove_if([](auto& pObj)
{
if ( pObj->needs_delete )
{
delete pObj;
return true;
}
else
return false;
});

Related

C++ GetAsyncKeyState() with private overridden attributes

I am trying to figure out how to use GetAsyncKeyState with private attributes forward and backwards from a base class. I need to be able to reset GetAsyncKeyState to other keypresses. Any idea?
Maybe overriding forward and backwards with other keypresses?
#include <iostream>
#include <windows.h>
#include <string>
#include<conio.h>
using namespace std;
bool reset_defaults = false;
class Base {
protected: // OR private
int forward = VK_UP, backwards = VK_DOWN;
public: //...
}
////////////
class Move : public Base {
public:
Base def;
int move() {
while (true) {
if (GetAsyncKeyState(forward) < 0){
cout << ("forward >>>\n");
if (GetAsyncKeyState(forward) == 0){
cout << ("Stopped\n");
}
}
if (GetAsyncKeyState(VK_SPACE) < 0){break;}
}
}
int main() {
Move move;
move.move();
}
Sorry, but I don't think I understand the whole logic of this yet.
PS UPDATE:
How can I override baseKeys values:
class MovementKeys {
protected:
int baseKeys(int default_key_forward, int default_key_backward, int default_key_left, int default_key_right){
default_key_forward = VK_UP;
default_key_backward = VK_DOWN;
default_key_left = VK_LEFT;
default_key_right = VK_RIGHT;
}
public:
int definedCommand(int default_key_forward, int default_key_backward, int default_key_left, int default_key_right) {
while (reset_defaults == false)
{
cout << ("HERE 1 \n");
if (GetAsyncKeyState(default_key_forward) < 0)
{
cout << ("forward\n");
}
if (GetAsyncKeyState(default_key_backward) < 0)
{
court << ("backwards\n");
}
if (GetAsyncKeyState(default_key_left) < 0)
{
cout << ("left\n");
}
if (GetAsyncKeyState(default_key_right) < 0)
{
cout << ("right\n");
}
if (GetAsyncKeyState(VK_SPACE) < 0) { break; }
}
return 0;
}
int derived_newKeys(int default_key_forward, int default_key_backward, int default_key_left, int default_key_right) {
return baseKeys(default_key_forward, default_key_backward, default_key_left, default_key_right);
}
You probably want to use member variables to store the keys. Instead of deriving the class with new keys, you set the variables in constructors (to default or to changed values) and can also change the key assignment later on.
You probably want to create a separate class, which reacts on the events.
#include <iostream>
#include <windows.h>
#include <conio.h>
using namespace std;
class World {
public:
void forward() { y--; };
void backward() { y++; };
void left() { x--; };
void right() { x++; };
private:
int x = 0;
int y = 0;
};
class MovementKeys {
// member variables
private:
// keep reference to world instead of copy; main() has to make sure World object outlives MovementKeys object
World& world;
int key_forward;
int key_backward;
int key_left;
int key_right;
public:
// constructor, which only sets world, but keeps the keys at their default settings
//
// world has to be initialized before the constructor function body
// as references have no default value
// put initialization in member initialization list
MovementKeys(World& w) : world(w)
{
key_forward = VK_UP;
key_backward = VK_DOWN;
key_left = VK_LEFT;
key_right = VK_RIGHT;
}
// constructor which modifies keys
MovementKeys(World& w, int change_key_forward, int change_key_backward, int change_key_left, int change_key_right) : world(w)
{
changeKeys(change_key_forward, change_key_backward, change_key_left, change_key_right);
}
// command loop controlled by keys
int definedCommand()
{
while (true)
{
cout << ("HERE 1 \n");
if (GetAsyncKeyState(key_forward) < 0)
{
cout << ("forward\n");
world.forward();
}
if (GetAsyncKeyState(key_backward) < 0)
{
cout << ("backwards\n");
world.backward();
}
if (GetAsyncKeyState(key_left) < 0)
{
cout << ("left\n");
world.left();
}
if (GetAsyncKeyState(key_right) < 0)
{
cout << ("right\n");
world.right();
}
// optionally change keys from within while loop
if (GetAsyncKeyState(VK_BACK) < 0)
{
key_forward = VK_RETURN;
}
if (GetAsyncKeyState(VK_SPACE) < 0)
{
break;
}
}
return 0;
}
// function for changing the keys stored in the member variables
// can be called by constructor or externally
void changeKeys(int change_key_forward, int change_key_backward, int change_key_left, int change_key_right)
{
key_forward = change_key_forward;
key_backward = change_key_backward;
key_left = change_key_left;
key_right = change_key_right;
}
};
int main()
{
World earth;
// use default keys, declares local variable and constructs MovementKeys object called move
MovementKeys move(earth);
move.definedCommand();
// use custom keys, share same world, declares local variable and constructs MovementKeys object called move2
// static_cast<int>() with a letter in a literal char parameter works, because the VK_ values of letter keys are the actual ASCII values (on purpose by Microsoft, I would assume)
MovementKeys move2(earth, static_cast<int>('W'), static_cast<int>('S'), static_cast<int>('A'), static_cast<int>('D'));
move2.definedCommand();
// change keys in move2
move2.changeKeys(VK_LBUTTON, VK_RBUTTON, VK_CONTROL, VK_SHIFT);
move2.definedCommand();
// run first one again for the fun of it
move.definedCommand();
}
Alternatively passing World& only, where it is used in definedCommand (and at the same time be able to use several worlds):
class World {
// ...
};
class MovementKeys {
// member variables without world, we can also put default value here
private:
int key_forward = VK_UP;
int key_backward = VK_DOWN;
int key_left = VK_LEFT;
int key_right = VK_RIGHT;
public:
// default constructor with no parameters, delegate to other constructor
// delegating not necessary, as the default values are set above anyway; just demonstrating various techniques for initializing member variables
MovementKeys() : MovementKeys(VK_UP, VK_DOWN, VK_LEFT, VK_RIGHT) {};
// constructor which modifies keys, put everything in member initialization list
MovementKeys(int change_key_forward, int change_key_backward, int change_key_left, int change_key_right) : key_forward(change_key_forward), key_backward(change_key_backward), key_left(change_key_left), key_right(change_key_right) {};
// command loop controlled by keys, pass World& here as parameter
int definedCommand(World& world)
{
while (true)
{
// ...
}
return 0;
}
void changeKeys(int change_key_forward, int change_key_backward, int change_key_left, int change_key_right)
{
// ...
}
};
int main()
{
// use default keys, declares local variable and constructs MovementKeys object called move
MovementKeys move;
// use custom keys, declares local variable and constructs MovementKeys object called move2
MovementKeys move2(static_cast<int>('W'), static_cast<int>('S'), static_cast<int>('A'), static_cast<int>('D'));
MovementKeys defaultMenuKeys;
World earth;
World moon;
World menu; // between moving in worlds, we want to control some settings in a menu
move.definedCommand(earth);
move2.definedCommand(earth);
move2.definedCommand(moon);
// change keys in move2
move2.changeKeys(VK_LBUTTON, VK_RBUTTON, VK_CONTROL, VK_SHIFT);
move2.definedCommand(earth);
defaultMenuKeys.definedCommand(menu);
// run first one again for the fun of it
move.definedCommand(moon);
}
You can introduce a (class) enum with a list of the states, why definedCommand() returns:
// outside or can be put into MovementKeys and henceforth used as MovementKeys::ReturnReason
class enum ReturnReason { EXIT, NEWKEYS, SHOWMENU, SWITCHWORLD };
// in class MovementKeys
ReturnReason definedCommand() {
// ...
return NEWKEYS;
// ...
return EXIT;
// ...
return SHOWMENU;
// ...
}
// in main()
ReturnReason r = definedCommand();
if (r == NEWKEYS)
move2.changeKeys(...);
else if (r == EXIT)
return 0;
If you use that 'trick' to also control the menu, it could make sense to use virtual inheritance now for World. As the normal World and the menu World probably react quite differently. (The base class (ancestor) would be World, which is recognized by MovementKeys. Your actual Worlds are objects of derived (children) classes, with more specific behaviour.
definedCommand then can be called and run with any derived class of the base class World.

flooding the views with update requests issue in observer pattern(C++)

I have some MVC code, it uses the observer mode, such as below:
void Model::ChangeMethod1()
{
m_A = m_A + 1;
...
Notify();
}
void Model::ChangeMethod2()
{
m_A = m_A + 2;
...
Notify();
}
void Model::ChangeMethod3()
{
ChangeMethod1();
ChangeMethod2();
Notify();
}
void Model::ChangeMethod4()
{
ChangeMethod1();
ChangeMethod2();
ChangeMethod3();
Notify();
}
There are many functions like ChangeMethodX which will make changes to the Model, and notify the viewers, and when the viewers receive the events, they will refresh/update themselves.
You see, each function ChangeMethodX has a Notify() function, which internally send an event to the observer.
But I don't want the observer receive too many events in the each function, because there will too many events, I would like each top level function call whether it has any internal function calls only send one update event to the viewer.
I think this is a very common issue that happens in many situations, such as the MVC mode, as a model will notify viewers to get updated. But we have to avoid the flooded events if the model changes several times inside a top level function call.
I thought of 2 possible approaches:
If the subject is completely under your control and this solution is not too invasive, you could add an optional parameter specifying whether the called ChangeMethodX is a top level function, like this:
void Model::ChangeMethod1(bool topLevel = true)
{
m_A = m_A + 1;
...
NotifyIfTopLevel(topLevel);
}
void Model::ChangeMethod2(bool topLevel = true)
{
m_A = m_A + 2;
...
NotifyIfTopLevel(topLevel);
}
void Model::ChangeMethod3(bool topLevel = true)
{
ChangeMethod1(false);
ChangeMethod2(false);
NotifyIfTopLevel(topLevel);
}
void Model::ChangeMethod4(bool topLevel = true)
{
ChangeMethod1(false);
ChangeMethod2(false);
ChangeMethod3(false);
NotifyIfTopLevel(topLevel);
}
void Model::NotifyIfTopLevel(bool topLevel)
{
if (topLevel)
Notify();
}
However, it is ugly most of the time and it could dirty your interface.
The second approach you could choose is on the other hand risky if you have to deal with concurrency. Moreover if you catch an exception and you handle it, you must remember to bring the object back in a correct state (is_changing-- if not called yet), otherwise the observers are not going to receive notifications anymore.
int is_changing = 0;
void Model::ChangeMethod1()
{
m_A = m_A + 1;
...
NotifyIfNotChanging();
}
void Model::ChangeMethod2()
{
m_A = m_A + 2;
...
NotifyIfNotChanging();
}
void Model::ChangeMethod3()
{
is_changing++;
ChangeMethod1();
ChangeMethod2();
is_changing--;
NotifyIfNotChanging();
}
void Model::ChangeMethod4()
{
is_changing++;
ChangeMethod1();
ChangeMethod2();
ChangeMethod3();
is_changing--;
NotifyIfNotChanging();
}
void Model::NotifyIfNotChanging()
{
if (is_changing == 0)
Notify();
}
If you have that many ChangeMethodX methods, maybe consider using an Aspect Oriented framework to separate the concern of notifying observers. Especially if you need to repeat is_changing++/-- or trivially the Notify call, moving them in the appropriate aspect class would definitely be more readable.
EDIT
As for the RAII approach, it is in my opinion kind of overused here since you do not have resources to release, creating and disposing objects every time is quite overkilling for your needs.
By the way, if you want to follow this path, then I recommend you to fix some code smells.
You are not encapsulating appropriately the SetTopLevelCall. It is not supposed to be public because the user of your class must not mess with it.
There is a new public class DeferredEventSender that is tightly coupled to your Model class. The worst part is that it is responsible for the Notify method, that should be called by the Model itself. Moreover, you are ruling out the possibility to need to access the Model private fields and functions.
Here is how I would face these issues, even though it is not perfect yet.
class Model
{
public:
Model()
{
}
~Model()
{
}
void ChangeMethod1();
void ChangeMethod2();
void ChangeMethod3();
void ChangeMethod4();
void Notify();
protected:
class DeferredEventSender
{
public:
DeferredEventSender(Model* m)
{
_m = m;
doCallNotify = _m->topLevel;
_m->topLevel = false;
}
~DeferredEventSender()
{
if (doCallNotify)
{
_m->Notify();
_m->topLevel = true;
}
}
Model* _m;
bool doCallNotify;
};
bool topLevel = true;
int m_A;
int m_B;
};
void Model::ChangeMethod1()
{
Model::DeferredEventSender sender(this);
m_A = m_A + 1;
}
...
I just follow Marco Luzzara's second approach, and create a simple demo C++ code, see below:
Revision 1:
#include <iostream>
using namespace std;
class Model
{
public:
Model()
: m_TopLevelCallScope(false)
{
}
~Model()
{
}
void ChangeMethod1();
void ChangeMethod2();
void ChangeMethod3();
void ChangeMethod4();
void Notify();
bool IsTopLevelCall()
{
return m_TopLevelCallScope;
}
void SetTopLevelCall(bool topLevel)
{
m_TopLevelCallScope = topLevel;
}
private:
// if this variable is true, it means a top level call scope is entered
// then all the inner call should not send event, the final event could
// send when the top level sender get destructed
bool m_TopLevelCallScope;
// other members
int m_A;
int m_B;
};
// this is a deferred notification
// each function should create a local object
// but only the top level object can finally send a notification
class DeferredEventSender
{
public:
DeferredEventSender(Model* model)
: m_Model(model)
{
if(m_Model->IsTopLevelCall() == false)
{
m_Model->SetTopLevelCall(true);
m_TopLevelCallScope = true;
}
else
{
m_TopLevelCallScope = false;
}
}
~DeferredEventSender()
{
if (m_TopLevelCallScope == true)
{
// we are exiting the top level call, so restore it to false
// it's time to send the notification now
m_Model->SetTopLevelCall(false);
m_Model->Notify();
}
// do nothing if m_TopLevelCallScope == false
// because this means we are in a inner function call
}
bool m_TopLevelCallScope;
Model* m_Model;
};
void Model::ChangeMethod1()
{
DeferredEventSender sender(this);
m_A = m_A + 1;
}
void Model::ChangeMethod2()
{
DeferredEventSender sender(this);
m_A = m_A + 2;
}
void Model::ChangeMethod3()
{
DeferredEventSender sender(this);
ChangeMethod1();
ChangeMethod2();
}
void Model::ChangeMethod4()
{
DeferredEventSender sender(this);
ChangeMethod1();
ChangeMethod2();
ChangeMethod3();
}
void Model::Notify()
{
cout << "Send event!" << endl;
}
int main()
{
Model m;
m.ChangeMethod1();
m.ChangeMethod2();
m.ChangeMethod3();
m.ChangeMethod4();
return 0;
}
And here is the output of the demo C++ code:
Send event!
Send event!
Send event!
Send event!
You see that in the main() function, I have only 4 function calls, and only 4 events is send.
The method I use is that I put a DeferredEventSender local object in each ChangeMethodX method, and if it is a top level function call, this object will have its member variable m_TopLevelCallScope set as true, if it is a inner function call, m_TopLevelCallScope is set as false.
When the DeferredEventSender local object leaves the scope, it will check to see if it is the top level object, if true, it will send the event, so all the inner function calls won't send events.
The demo code can be extended, so that events can be accumulated and stored in a std::queue<Event> in the DeferredEventSender object or Model object, and when the top DeferredEventSender object get destroyed, we can run a filter in the std::queue<Event>, and remove the duplicated events, and send the events we actually needed.
As suggested by Marco Luzzara, this is the modified version, thanks Marco Luzzara!
Revision 2:
#include <iostream>
using namespace std;
class Model
{
public:
Model()
{
}
~Model()
{
}
void ChangeMethod1();
void ChangeMethod2();
void ChangeMethod3();
void ChangeMethod4();
void Notify();
protected:
class DeferredEventSender
{
public:
DeferredEventSender(Model* m)
{
m_Model = m;
// the first instance of the DeferredEventSender will copy the status of m_TopLevel
// and all the later(inner) instances will have false m_TopLevel
m_DoCallNotify = m_Model->m_TopLevel;
m_Model->m_TopLevel = false;
}
~DeferredEventSender()
{
// we only call Notify on the top level DeferredEventSender
if (m_DoCallNotify)
{
m_Model->Notify();
m_Model->m_TopLevel = true;
}
}
Model* m_Model;
bool m_DoCallNotify;
};
bool m_TopLevel = true;
int m_A;
int m_B;
};
void Model::ChangeMethod1()
{
Model::DeferredEventSender sender(this);
m_A = m_A + 1;
}
void Model::ChangeMethod2()
{
Model::DeferredEventSender sender(this);
m_A = m_A + 2;
}
void Model::ChangeMethod3()
{
Model::DeferredEventSender sender(this);
ChangeMethod1();
ChangeMethod2();
}
void Model::ChangeMethod4()
{
Model::DeferredEventSender sender(this);
ChangeMethod1();
ChangeMethod2();
ChangeMethod3();
}
void Model::Notify()
{
cout << "Send event!" << endl;
}
int main()
{
Model m;
m.ChangeMethod1();
m.ChangeMethod2();
m.ChangeMethod3();
m.ChangeMethod4();
return 0;
}

0xcdcdcdcd while using this->

Hi im doing little project tomy school and keep getting weird for me error.
While calling one of methods in my object this pointer is set to 0xcdcdcdcd. i googled it and found some info about erasing memory or destroing objects before calling, but i make sure no destructors are called before.
World.h
class Organism;
class Human;
class World
{
private:
vector <Organism*> organisms;
vector <Organism*> organismsToAdd;
vector <string> logs;
int turn_;
void initializeWorld();
void drawInterface();
void drawInfo();
void drawOrganisms();
void nextTurn();
bool isPositionTaken(int x, int y);
Organism* getOrganism(int x, int y);
void queueOrganismToAdd(Organism* newOrganism);
void addQueuedOrganisms();
void generateStartOrganisms();
bool isPlayerAlive();
public:
void executeMove(Organism* moving, int toX, int toY); //here's the problem
bool isPositionValid(int x, int y);
World(int x, int y);
struct
{
int x_, y_;
} worldSize;
void startGame();
~World();
};
executeMove
void World::executeMove(Organism* moving, int toX, int toY)
{
cout << moving->getSign();
getch();
if (!isPositionTaken(toX, toY)) // <- here it brake
{
moving->setPosition(toX, toY);
}
else if (moving->getSign() == getOrganism(toX, toY)->getSign())
{
//multiply
//make log
}
else {
if (!moving->specialCollision((getOrganism(toX, toY)))) return;
if (!getOrganism(toX, toY)->specialCollision(moving)) return;
if (moving->getPower() >= getOrganism(toX, toY)->getPower())
{
//log
//delete losser
}
else
{
//log
//delete losser
}
moving->setPosition(toX, toY);
}
}
isPositioinTaken
bool World::isPositionTaken(int x, int y)
{
for (int i = 0; i < this->organisms.size(); ++i) // here this is set to 0xcdcdcdcd
{
if (organisms[i]->getPositionX() == x && organisms[i]->getPositionY() == y) return true;
}
return false;
}
Method isPositionTaken is worlking well in other parts of project so im totally lost if finding whats wrong, i aprreciate any help
Since the organisms member has a default constructor, the only way to see this behavior at the line you indicated is if the call to executeMove() was using a pointer which was uninitialized.
Something like:
World *ptr; // not initialized on stack
...
ptr->executeMove();
Or this method was called from another method with the same problem.

C++ Implementing a Button with member-function callback

I am trying to implement a simple GUI component in C++. The 'Button' class exists in a library that is completely de-coupled from the main program. I want to be able to pass a function-pointer to a button that can be ran upon clicking.
I had some success until I moved the 'button' from being a struct to class for readability and expandability. I reckon that it only worked by pure chance as now I get very random problems.
I basically have something like this:
typedef void(BaseMenu::*ClickAreaCallback)(Button*);
struct Message{
ClickAreaCallback func;
Button* clickArea;
BaseMenu* funObj;
};
The from my classes that subclass BaseMenu, I do something like this:
cb = (ButtonContainer::ClickAreaCallback)&TileSelectorScreen::setTileMode;
and set:
ClickAreaCallback to &cb (as well as funObj)
I then run it upon 'click' by doing:
m->funObj->*m->func)(m->clickArea);
This is obviously wrong as I've read there are problems passing non-static member functions and expecting them to run.
So, is what I am doing impossible? Is what I want possible by using plain C++ without boost or using -std=c++11. I'm limiting myself to the very basics so I can still compile for many platforms.
In short: I want a simple method of calling functions from a class that knows nothing of the class it's calling.
thanks in advance.
In principle there is nothing wrong with pointers to members.
See, e.g., the following code:
#include <iostream>
/** Some API */
struct Button {
virtual void OnClick() = 0;
};
struct BaseMenu {
void f1(Button* b) {
std::cout << "f1(Button*)\n";
b->OnClick();
}
void f2(Button* b) {
std::cout << "f2(Button*)\n";
b->OnClick();
}
void Update() {
}
};
typedef void(BaseMenu::*ClickAreaCallback)(Button*);
struct Message{
ClickAreaCallback func;
Button* clickArea;
BaseMenu* funObj;
};
/** Usage */
class OKButton : public Button {
void OnClick() {
std::cout << "OKButton::OnClick()\n";
}
};
int main(int nArg, char* args[]) {
// Fill message:
BaseMenu menu;
OKButton ok;
Message m1, m2;
m1.func = &BaseMenu::f1;
m1.funObj = &menu;
m1.clickArea = dynamic_cast<Button*>(&ok);
m2.func = &BaseMenu::f2;
m2.funObj = &menu;
m2.clickArea = dynamic_cast<Button*>(&ok);
(m1.funObj ->* m1.func)(m1.clickArea);
(m2.funObj ->* m2.func)(m2.clickArea);
}
But it looks like a conceptional error. You should not need the callback. The buttons should be derived from a base class and have virtual member functions that do the specific stuff.
There follows an example demonstrating the usage of inheritance instead of callbacks.
Note, that ButtonToggle is an example for storing the information inside the button and ButtonNotify is an example for the button notifying the menu.
#include <iostream>
#include <vector>
/** Some API */
struct Button {
double _area[4]; // rectangle x1,y1,x2,y2
Button(std::initializer_list<double> area) {
std::copy(area.begin(),area.begin()+4,_area);
}
virtual void OnClick() = 0;
};
class BaseMenu {
protected:
std::vector<Button*> _buttons;
public:
void Register(Button* btn) {
_buttons.push_back(btn);
}
void OnClick(double pt[2]) {
for(auto iBtn = _buttons.begin(); iBtn!=_buttons.end(); iBtn++) {
if( (*iBtn)->_area[0] <= pt[0] && pt[0] <= (*iBtn)->_area[2]
&& (*iBtn)->_area[1] <= pt[1] && pt[1] <= (*iBtn)->_area[3] ) {
(*iBtn)->OnClick();
}
}
}
};
struct MyMenu : public BaseMenu {
struct ButtonToggle: public Button {
bool _val;
ButtonToggle() :
Button( {0.0,0.0,1.0,1.0} )
{
_val = false;
}
void OnClick()
{
std::cout << "ButtonToggle::OnClick()\n";
_val = not(_val);
}
} buttonToggle;
void DoSomething() {
std::cout << "DoSomething()\n";
}
struct ButtonNotify: public Button {
MyMenu& _myMenu;
ButtonNotify(MyMenu& myMenu) :
Button( {2.0,0.0,3.0,1.0} ),
_myMenu(myMenu)
{}
void OnClick() {
_myMenu.DoSomething();
}
} buttonNotify;
MyMenu() :
buttonNotify(*this)
{
Register(&buttonToggle);
Register(&buttonNotify);
}
};
int main(int nArg, char* args[]) {
MyMenu menu;
double pt[2];
while(( std::cout << "\nCoordinates (end: -1 -1):",
std::cin >> pt[0] >> pt[1],
not( pt[0] == -1.0 and pt[1] == -1.0 ) )) {
menu.OnClick(pt);
}
}
/*
Local Variables:
compile-command: "g++ -g -std=c++11 test1.cc"
End:
*/

Strange destructor call in C++

I have those inheritance classes :
Base Class: Entity
Derived from Entity Classes: Actor, Obj, Enemy
The Base class Entity contains an obj of a user-defined-type that i called "CollisionStuff".
When i run my program the destructor of CollisionStuff is called after every CollisionStuff constructor call and every time game-loop goes on.
so my call is: why is this happening?
As you can see below, i allocate dinamically some arrays in the setRectangle method, the programm calls the destructor, it deletes my data and when i try to use them... it calls "_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));".
Thank you in before
here my code: Entity.h
enum e_Type {tActor = 0, tObj, tEnemy, tBackg};
class Entity
{
public:
Entity(void);
~Entity(void);
float getH();
float getW();
void setWH(float W, float H);
bool CreateSprite(std::string path);
sf::Sprite& getSprite();
void setType(e_Type type);
e_Type getType();
CollisionStuff getColStuff();
static std::list<Entity*> List;
protected:
sf::Sprite m_sprite;
sf::Texture m_texture;
float m_h;
float m_w;
e_Type m_type;
CollisionStuff m_colStuff;
void addToList();
};
CollisionStuff.h
class CollisionStuff
{
public:
CollisionStuff();
~CollisionStuff(void);
void setRectangle(int W, int H);
void followTheSprite(Entity entity);
private:
sf::Vector2f* m_a;
sf::Vector2f* m_b;
sf::Vector2f* m_c;
sf::Vector2f* m_d;
/* this member data are sides of rectangle used
to manage collisions between object throughout the scenario
a
-------------
| |
c | | d
| |
-------------
b
*/
};
CollisionStuff.cpp
CollisionStuff::CollisionStuff()
{
//setRectangle(0, 0);
}
void CollisionStuff::setRectangle(int W, int H)
{
m_a = new sf::Vector2f[W];
m_b = new sf::Vector2f[W];
m_c = new sf::Vector2f[H];
m_d = new sf::Vector2f[H];
}
void CollisionStuff::followTheSprite(Entity entity)
{
entity.getSprite().setOrigin(0, 0);
sf::Vector2f UpLeftVertex = entity.getSprite().getPosition();
for(int i = 0; i < entity.getW(); i++)
{
m_a[i].x = UpLeftVertex.x + i;
m_a[i].y = UpLeftVertex.y;
m_b[i].x = UpLeftVertex.x + i;
m_b[i].y = UpLeftVertex.y + entity.getH();
}
for(int i = 0; i < entity.getH(); i++)
{
m_c[i].x = UpLeftVertex.x;
m_c[i].y = UpLeftVertex.y + i;
m_d[i].x = UpLeftVertex.x + entity.getW();
m_d[i].y = UpLeftVertex.y + i;
}
}
CollisionStuff::~CollisionStuff(void)
{
delete [] m_a;
delete [] m_b;
delete [] m_c;
delete [] m_d;
}
EDIT
Thank you for the answers.
Example of CollisionStuff use
Actor.cpp (it's a derived class of Entity)
Actor::Actor(void)
{
if(!CreateSprite("D://Sprites//MainChar.png"))
{
std::cout << "Impossibile creare sprite" << std::endl;
}
else
{
std::cout << "Creazione sprite riuscita" << std::endl;
m_sprite.setPosition(100.0f, 365.0f);
m_sprite.setOrigin(20, 35);
//m_sprite.setPosition(190.0f, 382.5f); // 200, 400
setWH(40, 70);
m_health = 100;
m_status = Good;
setType(tActor);
m_jCounter = -1;
m_action = Null;
setColStuff();
}
}
void Actor::setColStuff()
{
m_colStuff.setRectangle(m_w, m_h);
}
void Actor::physic()
{
//setColStuff();
m_colStuff.followTheSprite(*this);
}
main.cpp
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "Platform");
std::list<Entity*>::iterator i;
Background BG;
Level1 FirstLev;
Actor Doodle;
while(window.isOpen())
{
sf::Event event;
if(window.pollEvent(event))
{
if (event.type == sf::Event::Closed)
window.close();
Doodle.inputEvts();
}
Doodle.act(Doodle.getAction());
Doodle.physic();
window.clear();
window.draw(BG.getSprite());
window.draw(Doodle.getSprite());
FirstLev.drawLevel(window);
window.display();
}
return 0;
}
It's really hard to tell from the bit of code that you posted, but if I had to guess I'd say it's probably related to this:
CollisionStuff getColStuff();
you're returning CollisionStuff by value, which means a new copy will be created by whoever is calling this. It'll have the same pointers that the original CollisionStuff object allocated, and it'll delete them when it goes out of scope, leaving the original one with dangling pointers.
You can try returning by reference or by pointer, but either way you should write a copy constructor and override the assignment operator for CollisionStuff (Rule of Three).
Another idea would be to use std::vector<sf::Vector2f> instead of allocating the sf::Vector2f array yourself.