Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION
FOUND?
someone wrote:
On 01/02/2012 03:11 AM, LR wrote:
someone wrote:
On 01/01/2012 10:03 AM, Juha Nieminen wrote:
someone<newsboost@gmail.com> wrote:
I think std::vector is a little easier to deal with.
Maybe... I'm just a little bit stupid and afraid. So...
Try it.
--- main.cpp ---
drawableObj allObjs; // must be global!
int main(int argc, char** argv)
{
drawableObj *testGearPtr =
new gearClass( .... ); // rotSpeed etc, etc... bla.bla
drawableObj *testGearPtr2 =
new gearClass( .... ); // rotSpeed etc, etc... bla.bla
If you have a global allObjs, how do these pointers make their way into
that object?
// ******* OpenGL starting... *******
glutInit(&argc, argv);
.... bla bla...
glutMainLoop(); // exits directly to OS from here...
return(0); // never comes here - just to satisfy compiler...
Odd, because it shouldn't be required at all.
class drawableObj
{
// private: // protected: // I don't have anything here
public:
// global+static pointer to all GRAPHICAL objs:
static vector<drawableObj*> pObjs;
Why is this static? Why not just make it a member class?
drawableObj(); // constructor
// destructor
virtual ~drawableObj();
// member functions
virtual void draw(); // <---used in openGL display loop
void showNumObjs();
void test();
};
class gearClass : public drawableObj
Ok, now I'm confused. Is drawableObj some sort of polymorphic base
class, or is it a container for a whole bunch of objects.
{
private:
public:
bool memAllocated; // IMPORTANT TO KNOW IF DELETE HAS BEEN CALLED
Use std::vector and this problem doesn't arise.
#include "gearClass.h" // for knowing "gearClass"-type
// NOT SURE ABOUT THIS, BUT COMPILER COMPLAINS IF NOT "EXTERN"...
extern vector<drawableObj*> drawableObj::pObjs;
Coupling your class with an external object made elsewhere probably
limits the utility of the class.
drawableObj::~drawableObj() // destructor
if ( ((gearClass*) drawableObj::pObjs[z])->memAllocated )
delete ((gearClass*) drawableObj::pObjs[z]);
Or use a shared pointer and avoid this.
--- gearClass.cpp ---
gearClass::gearClass() // constructor
{
drawableObj::pObjs.push_back((gearClass*) this); // ISN'T THIS NICE ??
... bla bla...
No. I don't think so. Using a global like this seems like a bad idea.
I think it's better to decouple things.
======== that was possible solution, please give some input ========
Final remarks:
I snipped a lot and just hit a few points. I think what you're doing is
asking for trouble.
FWIW, here's my suggestion. Most of it is just trace so you can see
what's going on. I consider this to be a snippet. For example, it would
be a better idea to put the classes and implementations in header and
source files.
You might want to try creating a new project, copying the code, and
seeing what happens.
-----------------------
#include <iostream>
#include <string>
#include <vector>
#include <memory>
class DrawObjectBase {
public:
DrawObjectBase() {
std::cout << "DrawObjectBase(" << this << ")" << std::endl;
}
virtual ~DrawObjectBase() {
std::cout << "~DrawObjectBase(" << this << ")" << std::endl;
}
virtual void draw(const std::string &someParameter) const {
std::cout
<< "DrawObjectBase::draw("
<< this
<< ","
<< someParameter
<< ")"
<< std::endl;
}
};
class Star : public DrawObjectBase {
public:
Star()
:
DrawObjectBase()
{
std::cout << "Star(" << this << ")" << std::endl;
}
~Star() {
std::cout << "~Star(" << this << ")" << std::endl;
}
void draw(const std::string &s) const {
std::cout << "Star::draw(" << this << "," << s << ")" << std::endl;
}
};
class Planet : public DrawObjectBase {
public:
Planet()
:
DrawObjectBase()
{
std::cout << "Planet(" << this << ")" << std::endl;
}
~Planet() {
std::cout << "~Planet(" << this << ")" << std::endl;
}
void draw(const std::string &s) const {
std::cout
<< "Planet::draw(" << this << "," << s << ")" << std::endl;
}
};
class DrawObjects {
// this isn't the best way to do this,
// just an example.
// a point of departure, not a destination.
public:
// maybe these typedefs should be classes on their own
typedef
std::tr1::shared_ptr<DrawObjectBase> DrawObjectBaseContainer;
typedef std::vector<DrawObjectBaseContainer> DrawObjectsContainer;
DrawObjectsContainer objects; // public isn't great here...
public:
DrawObjects() : objects() {} // or howver many you need.
void add(const DrawObjectBaseContainer &d) {
objects.push_back(DrawObjectBaseContainer(d));
}
void draw(const std::string &someParameter) const {
for(DrawObjectsContainer::const_iterator
i=objects.begin();
i!=objects.end();
i++) {
i->get()->draw(someParameter);
}
}
};
DrawObjects ourGlobalObjects;
void f() {
ourGlobalObjects
.add(DrawObjects::DrawObjectBaseContainer(new Star()));
ourGlobalObjects
.add(DrawObjects::DrawObjectBaseContainer(new Planet()));
ourGlobalObjects
.add(DrawObjects::DrawObjectBaseContainer(new Planet()));
ourGlobalObjects.draw("Draw Once");
ourGlobalObjects.draw("Draw Again");
}
int main() {
f();
exit(0); // because....
}
-------------------------------------------
And the output is,
DrawObjectBase(00345768)
Star(00345768)
DrawObjectBase(003468B8)
Planet(003468B8)
DrawObjectBase(00346880)
Planet(00346880)
Star::draw(00345768,Draw Once)
Planet::draw(003468B8,Draw Once)
Planet::draw(00346880,Draw Once)
Star::draw(00345768,Draw Again)
Planet::draw(003468B8,Draw Again)
Planet::draw(00346880,Draw Again)
~Star(00345768)
~DrawObjectBase(00345768)
~Planet(003468B8)
~DrawObjectBase(003468B8)
~Planet(00346880)
~DrawObjectBase(00346880)
----------------------------------