noob question - destructors - freeing memory...

S

someone

someone said:
someone wrote:
On 01/01/2012 10:03 AM, Juha Nieminen wrote:


Try it.

Done it!

(now I only need to somehow detect that std::vector destructors are also
being called when exit() happens, just so I can sleep better at night) -
I just wrote about this concern in another reply...
If you have a global allObjs, how do these pointers make their way into
that object?

Good question. They get pushed there ( into allObjs.pObjs to be precise
) from the constructors of derived class types, i.e:

class drawableObj
{
private:
public:
static vector<drawableObj*> pObjs;
..
}

With global scope, I declare this in top of main.cpp:

drawableObj allObjs; // must be global!


allObjs is of the base class type, i.e: drawableObj. I want to put all
graphical objects, with a reference into the base class. Here's my first
(currently also the only) derived graphical object type:

class gearClass : public drawableObj
{
// private
// public

gearClass::gearClass( ... ) // constructor
{
pObjs.push_back((gearClass*) this); // <---- HERE IS THE ANSWER
...
... etc
}
}

Isn't that an appropriate way of doing it?

Or is there better alternatives?
Odd, because it shouldn't be required at all.

Sure? Because main is supposed to return an integer, right?...

Not exactly sure, if I don't return anything, about if it'll complain
about missing int (I think so, but haven't tried it lately)...
Why is this static? Why not just make it a member class?

Exactly! I'm glad that you ask... Actually, since I put (with global
scope) - in top of main():

drawableObj allObjs;

Then I also thought that it didn't had to be static... I think I tried
to remove the static keyword (still public though)... But, the compiler
complains about it... Here's what I try:

1) removed the static word everywhere
2) then I get an error here :

--- file: helper.h ---
class drawableObj
{
public:
...
vector<drawableObj*> pObjs; // <--- LINE 47
...
};

--- file: helper.cpp ---
GLdouble findbox()
{
....
for (int z=0; z<(int) drawableObj::pObjs.size(); z++)
{
posX = ((gearClass*) drawableObj::pObjs[0])->posX; // 224
posY = ((gearClass*) drawableObj::pObjs[0])->posY; // 225
posZ = ((gearClass*) drawableObj::pObjs[0])->posZ; // 226
...
}
....
}

The 3 middle lines yield:

helper.cpp:224:37: error: from this location
helper.h:47:24: error: invalid use of non-static data member
‘drawableObj::pObjs

helper.cpp:225:37: error: from this location
helper.h:47:24: error: invalid use of non-static data member
‘drawableObj::pObjs

helper.cpp:226:37: error: from this location
helper.h:47:24: error: invalid use of non-static data member
‘drawableObj::pObjs


What's it complaining about?

(FYI: findbox finds the smallest+biggest x,y and z-values, thus this
is used to set the screen limits)

Ok, now I'm confused. Is drawableObj some sort of polymorphic base
class, or is it a container for a whole bunch of objects.

Yes, isn't it both? I think it's a polymorphic base class (although I'm
not too experienced with this) !

And remember the global definition in top of main.cpp:

drawableObj allObjs;
Use std::vector and this problem doesn't arise.
Ok.


Coupling your class with an external object made elsewhere probably
limits the utility of the class.

Hmmm. Not sure I understand exactly what I'm doing... Please elaborate -
I also don't understand fully how it "limits the utility of the class"
(because I'm not completely sure of what I'm doing)...
drawableObj::~drawableObj() // destructor
if ( ((gearClass*) drawableObj::pObjs[z])->memAllocated )
delete ((gearClass*) drawableObj::pObjs[z]);
Or use a shared pointer and avoid this.

But the idea is that I wanted polymorphism for all different kinds of
graphical objects. By shared pointer, do you mean a global pointer? I
don't like that idea... Here's why:

If I'm correct, then a shared pointer could only be used to point to all
(gearClass*) drawableObj (gearClass is a derived class, from
drawableObj). But I want the program to be able to handle more than one
class. Currently I only have gearClass deriving from drawableObj.
Suppose later I add extra classes like: cylinder, sphere, box, all 3
deriving from base class "drawableObj". Then I would like one single
"interface" to all those member functions that e.g. updates the display
- btw I found an error in my code. Now I update my display in a very
clean way, I think:

void display()
{
....
for (int z=0; z<(int) drawableObj::pObjs.size(); z++)
{
glPushMatrix();
(drawableObj::pObjs[z])->updateDisplay(); // could be any kind
glPopMatrix();
}
....
}

No. I don't think so. Using a global like this seems like a bad idea.
I think it's better to decouple things.

Can you elaborate on why you think it's not nice?

Isn't my updating of the screen (in display(), see right above) nice ?

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.

Ok - thank you. But first I want to compile it - then I can move it into
separate files... What compiler are you using? I get quite some errors with:

g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
You might want to try creating a new project, copying the code, and
seeing what happens.

Thank you... There are some new things to learn, I can see that... It
doesn't compile, so I'll just write what my compiler says:
-----------------------
#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;

test.cpp:66:9: error: ‘tr1’ in namespace ‘std’ does not name a type
typedef std::vector<DrawObjectBaseContainer> DrawObjectsContainer;

test.cpp:67:25: error: ‘DrawObjectBaseContainer’ was not declared in
this scope
test.cpp:67:48: error: template argument 1 is invalid
test.cpp:67:48: error: template argument 2 is invalid
DrawObjectsContainer objects; // public isn't great here...
public:
DrawObjects() : objects() {} // or howver many you need.
void add(const DrawObjectBaseContainer&d) {

test.cpp:71:20: error: ‘DrawObjectBaseContainer’ does not name a type
test.cpp:71:45: error: ISO C++ forbids declaration of ‘d’ with no type
[-fpermissive]
objects.push_back(DrawObjectBaseContainer(d));

test.cpp: In member function ‘void DrawObjects::add(const int&)’:
test.cpp:72:17: error: request for member ‘push_back’ in
‘((DrawObjects*)this)->DrawObjects::eek:bjects’, which is of non-class type
‘DrawObjects::DrawObjectsContainer {aka int}’
test.cpp:72:52: error: ‘DrawObjectBaseContainer’ was not declared in
this scope
test.cpp: In member function ‘void DrawObjects::draw(const string&) const’:
}
void draw(const std::string&someParameter) const {
for(DrawObjectsContainer::const_iterator
i=objects.begin();

test.cpp:75:35: error: invalid use of qualified-name ‘::const_iterator’
test.cpp:75:50: error: expected ‘;’ before ‘i’
test.cpp:75:50: error: ‘i’ was not declared in this scope
test.cpp:75:60: error: request for member ‘begin’ in ‘((const
DrawObjects*)this)->DrawObjects::eek:bjects’, which is of non-class type
‘const DrawObjectsContainer {aka const int}’
i!=objects.end();

test.cpp:76:28: error: request for member ‘end’ in ‘((const
DrawObjects*)this)->DrawObjects::eek:bjects’, which is of non-class type
‘const DrawObjectsContainer {aka const int}’
test.cpp:76:33: error: expected ‘)’ before ‘;’ token

test.cpp:77:21: error: ‘i’ was not declared in this scope
test.cpp:77:24: error: expected ‘;’ before ‘)’ token
i->get()->draw(someParameter);
}
}
};

DrawObjects ourGlobalObjects;

void f() {

ourGlobalObjects
.add(DrawObjects::DrawObjectBaseContainer(new Star()));

test.cpp:88:14: error: ‘DrawObjectBaseContainer’ is not a member of
‘DrawObjects’
ourGlobalObjects
.add(DrawObjects::DrawObjectBaseContainer(new Planet()));

test.cpp:90:14: error: ‘DrawObjectBaseContainer’ is not a member of
‘DrawObjects’
ourGlobalObjects
.add(DrawObjects::DrawObjectBaseContainer(new Planet()));

test.cpp:92:14: error: ‘DrawObjectBaseContainer’ is not a member of
‘DrawObjects’
ourGlobalObjects.draw("Draw Once");
ourGlobalObjects.draw("Draw Again");
}

int main() {
f();
exit(0); // because....
}


hmmmm.... Do I need to enable some compiler switch? You using MS visual
studio? I guess you're not using G++ with all these errors I get, are you?
-------------------------------------------

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)
----------------------------------

Sounds very nice too... Unfortunately, the example doesn't compile
here... I'll try to take a closer look tomorrow evening, I guess...

Thank you...
 
S

someone

If the destructor for a class is called, the destructors of it's members
will be destroyed as well, so if ~gearClass is called, the vectors
destructors will be called.
If the only place you call deAllocate is in your destructor, there is no
need to call clear(), as this is handled by the std::vector destructor.

Yes, I thought so...
Finally, in your constructor, you can use the std::vector( std::size_t
n, T = T(), Allocator = Allocator() ) constructor to create the vector
with the correct size, rather then using the default constructor and
then calling resize().

eg. instead of
gearClass()
{
cpp_X.resize( size );
cpp_Y.resize( size );
cpp_Z.resize( size );
}

use
gearClass()
: cpp_X( size ), cpp_Y( size ), cpp_Z( size )
{}

Ok, so it saves a tiny bit of cpu cycles right?

I think I'll do that, because it's probably more "clean" to initialize
it to be the correct size from the beginning instead of rezising it...

Thank you..
 
L

LR

(now I only need to somehow detect that std::vector destructors are also
being called when exit() happens, just so I can sleep better at night) -
I just wrote about this concern in another reply...

Write a little class that prints something in the dtor. Then try it in
a std::vector. This is why std::shared_ptr can clean up after itself.
std::vector tries to dtor every entry, and std::shared_ptr dtors the
thing it points to, if there is only one point to the thing left.

For example, I wrote this little function using the class hierarchy I
previously posted, (I compiled this using a recent version of MinGW with
-std=c++0x

void g() {
std::shared_ptr<DrawObjectBase> t1(new Star());
std::cout << "t1.use_count() " << t1.use_count() << std::endl;
std::shared_ptr<DrawObjectBase> t2(t1);
std::cout << "t1.use_count() " << t1.use_count() << std::endl;
std::cout << "t2.use_count() " << t2.use_count() << std::endl;
t1->draw("AA");
t2->draw("BB");
}

and the output was

DrawObjectBase(0x3e2768)
Star(0x3e2768)
t1.use_count() 1
t1.use_count() 2
t2.use_count() 2
Star::draw(0x3e2768,AA)
Star::draw(0x3e2768,BB)
~Star(0x3e2768)
~DrawObjectBase(0x3e2768)


class gearClass : public drawableObj
{
// private
// public

gearClass::gearClass( ... ) // constructor
{
pObjs.push_back((gearClass*) this); // <---- HERE IS THE ANSWER
...
... etc
}
}

Isn't that an appropriate way of doing it?

I think that you're coupling, that is, creating a dependency in your
class on a global. I don't think that's a good idea.

Why are you casting the this pointer of gearClass to (gearClass*)?
Isn't it already a (gearClass*)?


Sure? Because main is supposed to return an integer, right?...

I'm sure. Because main is not required to return an int. I'm surprised
that compilers are still complaining about this. Time to upgrade?
Exactly! I'm glad that you ask... Actually, since I put (with global
scope) - in top of main():

drawableObj allObjs;

[snip stuff about static]
What's it complaining about?

I'm not sure.
Yes, isn't it both? I think it's a polymorphic base class (although I'm
not too experienced with this) !

Why is it both? Why not make two classes, one is the base class of Gear
and whatever other classes you intend to have a draw method that
inherits from the base. And another class that is a container for a
collection of instances of these classes. Or rather a container for a
collection of pointers to instances of these classes.

Hmmm. Not sure I understand exactly what I'm doing... Please elaborate -
I also don't understand fully how it "limits the utility of the class"
(because I'm not completely sure of what I'm doing)...

For one thing, when you bury uses of your global in classes like Gear,
you're letting yourself in for a lot of work if things ever changes.
drawableObj::~drawableObj() // destructor
if ( ((gearClass*) drawableObj::pObjs[z])->memAllocated )
delete ((gearClass*) drawableObj::pObjs[z]);
Or use a shared pointer and avoid this.

But the idea is that I wanted polymorphism for all different kinds of
graphical objects. By shared pointer, do you mean a global pointer? I
don't like that idea... Here's why:

All different kinds? Or all different kinds that inherit a draw method?

It is possible to make collections of objects that have different
interfaces. You may want to take a look at boost::variant.

Some of what you've written implies that you not all of your classes
will share the same base class with gearClass. Is this true?

If I'm correct, then a shared pointer could only be used to point to all
(gearClass*) drawableObj (gearClass is a derived class, from
drawableObj). But I want the program to be able to handle more than one
class. Currently I only have gearClass deriving from drawableObj.
Suppose later I add extra classes like: cylinder, sphere, box, all 3
deriving from base class "drawableObj". Then I would like one single
"interface" to all those member functions that e.g. updates the display

Like the Star and Planet classes in my previous example? Or is there
something else that you'd like all of these classes to do?

In any case, you'd use std::shared_ptr to point to the base class of
your classes. Not to each individual class. In your case,
std::shared_ptr<drawableObj>. Then, so long as your other classes,
cylinder, sphere and box all inherit from drawableObj, you'll get the
behavior you want for each class, ie whatever implementation you've
written for void draw() for each class is what you'll get.

You may also want to have a look at dynamic_cast.

(drawableObj::pObjs[z])->updateDisplay(); // could be any kind

Any kind of pointer to a drawableObj. So far you only have gearClass.


Ok - thank you. But first I want to compile it - then I can move it into
separate files...

I wouldn't bother. It's just an example.

What compiler are you using? I get quite some errors with:

g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1

I tried MinGW 4.6.1. If you change the std::tr1::.. to std::.. it
should compile. I also used the -std=c++0x compiler argument.
It
doesn't compile, so I'll just write what my compiler says:

The above ought to take care of the errors you posted. I hope.
 
S

someone

Write a little class that prints something in the dtor. Then try it in
a std::vector. This is why std::shared_ptr can clean up after itself.
std::vector tries to dtor every entry, and std::shared_ptr dtors the
thing it points to, if there is only one point to the thing left.

For example, I wrote this little function using the class hierarchy I
previously posted, (I compiled this using a recent version of MinGW with
-std=c++0x

void g() {
std::shared_ptr<DrawObjectBase> t1(new Star());
std::cout<< "t1.use_count() "<< t1.use_count()<< std::endl;
std::shared_ptr<DrawObjectBase> t2(t1);
std::cout<< "t1.use_count() "<< t1.use_count()<< std::endl;
std::cout<< "t2.use_count() "<< t2.use_count()<< std::endl;
t1->draw("AA");
t2->draw("BB");
}

What exactly is your command line for compiling?
and the output was

DrawObjectBase(0x3e2768)
Star(0x3e2768)
t1.use_count() 1
t1.use_count() 2
t2.use_count() 2
Star::draw(0x3e2768,AA)
Star::draw(0x3e2768,BB)
~Star(0x3e2768)
~DrawObjectBase(0x3e2768)

Would be much better if I could run it too :)

I installed minGW on linux and tried this:

x86_64-w64-mingw32-c++ -std=c++0x test.cpp
(response: LOTS of errors, like yesterday)

I think that you're coupling, that is, creating a dependency in your
class on a global. I don't think that's a good idea.

But I need something that is global. Because it's impossible to pass any
data into the glutmainloop, if nothing is global.

The answer is just: What global parameter is sufficient? What do you
propose instead of the way I did it, thanks?
Why are you casting the this pointer of gearClass to (gearClass*)?
Isn't it already a (gearClass*)?

Ah, stupid - my mistake. I removed it now, thanks a lot (I previously
had some trouble with referencing gearClass with a pointer to the base
class, and before I made that specific member function virtual, I had to
make such a cast like this in my poorly written noob code :) )!

Thank you very much for spotting it and telling/asking about it! It's
fixed now (cast removed...)...
I'm sure. Because main is not required to return an int. I'm surprised
that compilers are still complaining about this. Time to upgrade?

Honestly, I cannot remember why I made main return an int. Maybe I just
did it because for many years ago I learnt it or maybe I found something
(old, posts perhaps) on google, telling me to do it...
Exactly! I'm glad that you ask... Actually, since I put (with global
scope) - in top of main():

drawableObj allObjs;

[snip stuff about static]
What's it complaining about?

I'm not sure.

Damn... Ok, I'll look at it later - maybe in the weekend and try to fix
this static problem...

Thanks for looking...

Why is it both? Why not make two classes, one is the base class of Gear
and whatever other classes you intend to have a draw method that
inherits from the base. And another class that is a container for a
collection of instances of these classes. Or rather a container for a
collection of pointers to instances of these classes.

Maybe... Could possible be made... But why make 2 global classes, when I
can put everything in a single global class?

*That* was my rationale (best to have one single global class to put all
things required by glut and elsewhere, for purpose of simplicity)...
For one thing, when you bury uses of your global in classes like Gear,
you're letting yourself in for a lot of work if things ever changes.

Ok, but the "drawableObj" base class, I think is something I want to
keep. I'll just make different derived classes, in order to paint/draw
different graphical stuff on the screen...
drawableObj::~drawableObj() // destructor

if ( ((gearClass*) drawableObj::pObjs[z])->memAllocated )
delete ((gearClass*) drawableObj::pObjs[z]);
Or use a shared pointer and avoid this.

But the idea is that I wanted polymorphism for all different kinds of
graphical objects. By shared pointer, do you mean a global pointer? I
don't like that idea... Here's why:

All different kinds? Or all different kinds that inherit a draw method?

I make (what I call) my "graphical objects" myself and I make them so
they *all* inherit a draw method... If they don't have a draw-method,
then they're not something I plan on deriving from drawableObj...

And there's nothing else than graphical objects (with a draw method) in
my program... Because only the graphical objects needs some "global"
access from "glutmainloop"...
It is possible to make collections of objects that have different
interfaces. You may want to take a look at boost::variant.

hmmm. I found an interesting description here:

http://www.boost.org/doc/libs/1_48_0/doc/html/variant.html

Might take a closer look at it, in the weekend (=more spare time), thank
you...
Some of what you've written implies that you not all of your classes
will share the same base class with gearClass. Is this true?

No, sorry, not true. All my classes will derive from the same base class
as gearClass... Then I use polymorphism inside glutmainloop to update
the graphical animation on the screen...
Like the Star and Planet classes in my previous example? Or is there

Exactly! At least I think so, based on the output you showed (because I
haven't compiled it without errors yet, will try a bit later again)...
something else that you'd like all of these classes to do?

Nope... They just need to update an animation, so I only need something
like your draw-function in the Star and Planet-example...
In any case, you'd use std::shared_ptr to point to the base class of
your classes. Not to each individual class. In your case,
std::shared_ptr<drawableObj>. Then, so long as your other classes,
cylinder, sphere and box all inherit from drawableObj, you'll get the
behavior you want for each class, ie whatever implementation you've
written for void draw() for each class is what you'll get.

Yep, thank you. It's great...
You may also want to have a look at dynamic_cast.

Sorry, for what (it's true that I need it, because I suck so bad at
using and understanding it, but maybe you're saying it because I do
something wrong in my program?)? :)
(drawableObj::pObjs[z])->updateDisplay(); // could be any kind

Any kind of pointer to a drawableObj. So far you only have gearClass.

Yep (more will come within a few weeks) ! :)
I wouldn't bother. It's just an example.
Ok.


I tried MinGW 4.6.1. If you change the std::tr1::.. to std::.. it
should compile. I also used the -std=c++0x compiler argument.


WOW... I just made it work, with these two tiny changes, see below!

The above ought to take care of the errors you posted. I hope.

You're absolutely right... Thank you very much. I'll study the example a
bit closer tonight when I come home (I am at work, currently)...

Incredible how many errors just disappeared by:

1) Search and replace std::tr1::.. to std::...

2) Compile like this: g++ -std=c++0x -Wall test.cpp


Thank you!
 
L

LR

someone said:
But I need something that is global. Because it's impossible to pass any
data into the glutmainloop, if nothing is global.

Yes. But you're filling your global with pointers to drawableObjs. The
global that you use for that should have a method that more or less
takes a pointer to a drawableObj and sticks it in a container in the
instance of the global class.

I'm not saying that what you suggest isn't possible. I just think it
makes for some awkwardness if you ever want to use a different
container, or use the class for some code where the container you're
using isn't available.

But in some ways it's an aesthetic choice, not a technical one.

The answer is just: What global parameter is sufficient? What do you
propose instead of the way I did it, thanks?

See my previously posted example.



Maybe... Could possible be made... But why make 2 global classes, when I
can put everything in a single global class?

Because it's confusing. IMHO it's nice to ask about a class, What does
it do or what is its purpose?

A floor wax or a dessert topping but not both.
http://snltranscripts.jt.org/75/75ishimmer.phtml

// the thing that is inherited by gear, sphere, etc..
class DrawableObjectBase;

// an instance of this will contains the pointers to your instances of
instances of classes that inherit from DrawableObjectBase.
class DrawableObjectsContainer;

I think combining those purposes into,
class DrawableObjectBaseAndDrawableObjectsContainer;
just makes trouble.

But maybe that's just me. YMMV.

*That* was my rationale (best to have one single global class to put all
things required by glut and elsewhere, for purpose of simplicity)...

If it works for you, fine. I think it makes things harder and more
difficult to understand. But IMHO you ought to do things that are clear
for you.
 
G

Garrett Hartshaw

Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION
FOUND?


Honestly, I cannot remember why I made main return an int. Maybe I just
did it because for many years ago I learnt it or maybe I found something
(old, posts perhaps) on google, telling me to do it...

um... main *does* need to return an int.
 
L

LR

Garrett said:
um... main *does* need to return an int.

Yes. I could have said that better. main doesn't have to have a return
statement in it.

From n3242 Main function 3.6.1.5
[...] If control reaches the end of main without encountering a return
statement, the effect is that of executing
return 0;
 
G

Garrett Hartshaw

Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION
FOUND?


Garrett said:
upgrade?

I
just

um... main *does* need to return an int.

Yes. I could have said that better. main doesn't have to have a return
statement in it.

From n3242 Main function 3.6.1.5
[...] If control reaches the end of main without encountering a return
statement, the effect is that of executing
return 0;

Ahh... most compilers will still give an error about not returning a
value from a non-void function. It's probably good to make the return
0 explicit anyways.
 
L

LR

Garrett said:
From n3242 Main function 3.6.1.5
[...] If control reaches the end of main without encountering a return
statement, the effect is that of executing
return 0;

Ahh... most compilers will still give an error about not returning a
value from a non-void function. It's probably good to make the return
0 explicit anyways.

Good point. Although the compilers I use don't seem to have that problem.

But speaking of that, since the OP has some portability issues, I should
add that using boost's shared_ptr might be the thing to do, if that's
what the ends up doing, to avoid the whole std:: v. std::tr1 problem if
that's an issue.
 
S

someone

Yes. But you're filling your global with pointers to drawableObjs. The
global that you use for that should have a method that more or less
takes a pointer to a drawableObj and sticks it in a container in the
instance of the global class.

Ok... I'll think about it, maybe you're right :)
I'm not saying that what you suggest isn't possible. I just think it
makes for some awkwardness if you ever want to use a different
container, or use the class for some code where the container you're
using isn't available.

But in some ways it's an aesthetic choice, not a technical one.

Roger that.
See my previously posted example.
Ok.


Because it's confusing. IMHO it's nice to ask about a class, What does
it do or what is its purpose?

A floor wax or a dessert topping but not both.
http://snltranscripts.jt.org/75/75ishimmer.phtml

// the thing that is inherited by gear, sphere, etc..
class DrawableObjectBase;

// an instance of this will contains the pointers to your instances of
instances of classes that inherit from DrawableObjectBase.
class DrawableObjectsContainer;

I think combining those purposes into,
class DrawableObjectBaseAndDrawableObjectsContainer;
just makes trouble.

But maybe that's just me. YMMV.

I see...

But maybe you're right... I think you're more professional than me :)
I'll think about it and maybe redo it later when I have more time...
If it works for you, fine. I think it makes things harder and more
difficult to understand. But IMHO you ought to do things that are clear
for you.

It's very nice to hear/read how other people would do it... Thank you
very much for that! :)
 
S

someone

Garrett said:
From n3242 Main function 3.6.1.5
[...] If control reaches the end of main without encountering a return
statement, the effect is that of executing
return 0;

Ahh... most compilers will still give an error about not returning a
value from a non-void function. It's probably good to make the return
0 explicit anyways.

Good point. Although the compilers I use don't seem to have that problem.

But speaking of that, since the OP has some portability issues, I should
add that using boost's shared_ptr might be the thing to do, if that's
what the ends up doing, to avoid the whole std:: v. std::tr1 problem if
that's an issue.

I don't even know what std:: v and std::tr1 means, but I'll look at
std::tr1 in the weekend and study the previously-posted "planets"-code
which use it...

Anyway - I'll also read about boost's shared_ptr in the weekend so I'll
hopefully understand it (or the most important things in it) within 1
week...

Thank you all...
 
L

LR

someone said:
I don't even know what std:: v and std::tr1 means, but I'll look at
std::tr1 in the weekend and study the previously-posted "planets"-code
which use it...

Just that you're using more than one compiler.

Of the two I currently use, one of them has std::tr1::shared_ptr and the
other one, which I think is more current, has std::shared_ptr.

So maybe this is something you want to check if you have to write
portable code.
 
S

someone

Just that you're using more than one compiler.

Of the two I currently use, one of them has std::tr1::shared_ptr and the
other one, which I think is more current, has std::shared_ptr.

So maybe this is something you want to check if you have to write
portable code.

Yes, definately, thanks... I'll look at it and google for previous
discussions/examples about it and perhaps ask in a new thread, if things
get too complicated for me :)

Thank you.
 
J

Joe keane

We had lots of discussion about whether an allocation with "new" still
counts as a memory leak when the programmer intentionally left out the
matching "delete" because the OS will re-claim the memory anyway. I
tend to say that this should not be considered a memory leak, even if
this makes the definition of a memory leak a bit harder.

One day someone is going to think it's a cool idea that your objects are
in shared memory, or in some memory-mapped files, in which case you have
a losing ticket.

It's very nice when you get to the main() last line the same as the
first line: nothing.
 
M

MikeWhy

Joe keane said:
One day someone is going to think it's a cool idea that your objects are
in shared memory, or in some memory-mapped files, in which case you have
a losing ticket.

Aren't those the precise conditions that the standard delete would cause
problems? You would need a custom allocator, to start.
It's very nice when you get to the main() last line the same as the
first line: nothing.

Yup. Agree fully. With the addition that allocations made during
initialization by static objects also follow suit.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top