Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #12887 > unrolled thread

noob question - destructors - freeing memory...

Started bysomeone <newsboost@gmail.com>
First post2011-12-31 02:43 +0100
Last post2011-12-31 18:18 +0100
Articles 20 on this page of 78 — 13 participants

Back to article view | Back to comp.lang.c++


Contents

  noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 02:43 +0100
    Re: noob question - destructors - freeing memory... "MikeWhy" <boat042-nospam@yahoo.com> - 2011-12-30 20:06 -0600
      Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 03:33 +0100
        Re: noob question - destructors - freeing memory... "MikeWhy" <boat042-nospam@yahoo.com> - 2011-12-30 21:22 -0600
          Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 04:57 +0100
            Re: noob question - destructors - freeing memory... "MikeWhy" <boat042-nospam@yahoo.com> - 2011-12-30 22:28 -0600
              Re: noob question - destructors - freeing memory... "MikeWhy" <boat042-nospam@yahoo.com> - 2011-12-30 22:43 -0600
              Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 05:49 +0100
                Re: noob question - destructors - freeing memory... "MikeWhy" <boat042-nospam@yahoo.com> - 2011-12-30 23:56 -0600
                  Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 07:07 +0100
                    Re: noob question - destructors - freeing memory... Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-12-31 01:50 -0800
                      Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 18:13 +0100
                        Re: noob question - destructors - freeing memory... Nobody <nobody@nowhere.com> - 2012-01-01 08:37 +0000
                        Re: noob question - destructors - freeing memory... LR <lruss@superlink.net> - 2012-01-01 10:54 -0500
                          Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 00:33 +0100
                            Re: noob question - destructors - freeing memory... "MikeWhy" <boat042-nospam@yahoo.com> - 2012-01-01 19:20 -0600
                              Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 03:55 +0100
                                Re: noob question - destructors - freeing memory... Stefan Ensslen <stefan@zollsoft.de> - 2012-01-02 04:32 -0800
                                  Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 17:40 +0100
                                    Re: noob question - destructors - freeing memory... Dombo <dombo@disposable.invalid> - 2012-01-02 19:14 +0100
                                      Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 21:30 +0100
                                  Re: noob question - destructors - freeing memory... jgk@panix.com (Joe keane) - 2012-01-07 23:23 +0000
                                    Re: noob question - destructors - freeing memory... "MikeWhy" <boat042-nospam@yahoo.com> - 2012-01-07 17:43 -0600
                            Re: noob question - destructors - freeing memory... Garrett Hartshaw <ghartshaw@gmail.com> - 2012-01-01 22:54 -0500
                              Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 05:29 +0100
                        Re: noob question - destructors - freeing memory... Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-01-01 13:38 -0800
                          Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 00:35 +0100
        Re: noob question - destructors - freeing memory... "Bo Persson" <bop@gmb.dk> - 2011-12-31 12:55 +0100
    Re: noob question - destructors - freeing memory... Garrett Hartshaw <ghartshaw@gmail.com> - 2011-12-30 22:50 -0500
      Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 05:37 +0100
        Re: noob question - destructors - freeing memory... LR <lruss@superlink.net> - 2011-12-31 01:07 -0500
          Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 08:54 +0100
            Re: noob question - destructors - freeing memory... Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-12-31 02:05 -0800
              Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 18:22 +0100
                Re: noob question - destructors - freeing memory... Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-01-01 13:45 -0800
                  Re: noob question - destructors - freeing memory... Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-01-02 12:17 +0000
                    Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 17:48 +0100
                      Re: noob question - destructors - freeing memory... Jorgen Grahn <grahn+nntp@snipabacken.se> - 2012-01-02 20:02 +0000
                Re: noob question - destructors - freeing memory... Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-01-01 13:42 -0800
        Re: noob question - destructors - freeing memory... Nick Keighley <nick_keighley_nospam@hotmail.com> - 2011-12-31 01:52 -0800
          Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 18:23 +0100
        Re: noob question - destructors - freeing memory... Garrett Hartshaw <ghartshaw@gmail.com> - 2011-12-31 12:35 -0500
          Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 00:47 +0100
    Re: noob question - destructors - freeing memory... Juha Nieminen <nospam@thanks.invalid> - 2011-12-31 09:40 +0000
      Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 18:26 +0100
        Re: noob question - destructors - freeing memory... Garrett Hartshaw <ghartshaw@gmail.com> - 2011-12-31 13:00 -0500
        Re: noob question - destructors - freeing memory... Nobody <nobody@nowhere.com> - 2012-01-01 08:57 +0000
          Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 00:43 +0100
        Re: noob question - destructors - freeing memory... Juha Nieminen <nospam@thanks.invalid> - 2012-01-01 09:03 +0000
          Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 00:49 +0100
            Re: noob question - destructors - freeing memory... LR <lruss@superlink.net> - 2012-01-01 21:11 -0500
              Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? someone <newsboost@gmail.com> - 2012-01-02 05:23 +0100
                Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION
 FOUND? Garrett Hartshaw <ghartshaw@gmail.com> - 2012-01-02 00:14 -0500
                  Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? someone <newsboost@gmail.com> - 2012-01-02 17:55 +0100
                  Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? someone <newsboost@gmail.com> - 2012-01-02 22:17 +0100
                    Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION
 FOUND? Garrett Hartshaw <ghartshaw@gmail.com> - 2012-01-02 16:40 -0500
                      Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? someone <newsboost@gmail.com> - 2012-01-03 00:48 +0100
                Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? LR <lruss@superlink.net> - 2012-01-02 14:47 -0500
                  Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? someone <newsboost@gmail.com> - 2012-01-03 00:43 +0100
                    Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? LR <lruss@superlink.net> - 2012-01-02 20:30 -0500
                      Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? someone <newsboost@gmail.com> - 2012-01-03 19:08 +0100
                        Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? LR <lruss@superlink.net> - 2012-01-03 17:46 -0500
                          Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? someone <newsboost@gmail.com> - 2012-01-04 21:11 +0100
                            Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? LR <lruss@superlink.net> - 2012-01-04 18:56 -0500
                        Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION
 FOUND? Garrett Hartshaw <ghartshaw@gmail.com> - 2012-01-03 19:49 -0500
                          Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? LR <lruss@superlink.net> - 2012-01-03 21:51 -0500
                            Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION
 FOUND? Garrett Hartshaw <ghartshaw@gmail.com> - 2012-01-03 23:37 -0500
                              Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? LR <lruss@superlink.net> - 2012-01-04 14:24 -0500
                                Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? someone <newsboost@gmail.com> - 2012-01-04 21:20 +0100
                                  Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? LR <lruss@superlink.net> - 2012-01-04 18:51 -0500
                                    Re: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND? someone <newsboost@gmail.com> - 2012-01-05 07:32 +0100
            Re: noob question - destructors - freeing memory... Garrett Hartshaw <ghartshaw@gmail.com> - 2012-01-01 23:02 -0500
              Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 05:33 +0100
              Re: noob question - destructors - freeing memory... "io_x" <a@b.c.invalid> - 2012-01-02 11:05 +0100
            Re: noob question - destructors - freeing memory... Juha Nieminen <nospam@thanks.invalid> - 2012-01-02 06:22 +0000
              Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2012-01-02 18:03 +0100
    Re: noob question - destructors - freeing memory... "Bo Persson" <bop@gmb.dk> - 2011-12-31 12:51 +0100
      Re: noob question - destructors - freeing memory... someone <newsboost@gmail.com> - 2011-12-31 18:18 +0100

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#12923

Fromsomeone <newsboost@gmail.com>
Date2011-12-31 18:23 +0100
Message-ID<jdngej$619$2@dont-email.me>
In reply to#12904
On 12/31/2011 10:52 AM, Nick Keighley wrote:
> On Dec 31, 4:37 am, someone<newsbo...@gmail.com>  wrote:
>> On 12/31/2011 04:50 AM, Garrett Hartshaw wrote:
>>

>>> If this is an issue, a smart pointer (boost::shared_ptr,
>>> boost::scoped_ptr, etc:) should be used.
>>
>> Ooh, damn...
>>
>> I hoped, I could avoid having to learn something new and timeconsuming
>> like boost...
>>
>> Isn't there an easier solution without including more libraries?
>
> std::auto_ptr
>
> though I believe this is now deprecated. Hasn't been removed though
> and does the job.

I'll try to google that, and look for working code examples - thanks...

[toc] | [prev] | [next] | [standalone]


#12925

FromGarrett Hartshaw <ghartshaw@gmail.com>
Date2011-12-31 12:35 -0500
Message-ID<almarsoft.7878142519409512659@news.eternal-september.org>
In reply to#12895
On Sat, 31 Dec 2011 05:37:56 +0100, someone <newsboost@gmail.com> 
wrote:
> On 12/31/2011 04:50 AM, Garrett Hartshaw wrote:
> > If this is an issue, a smart pointer (boost::shared_ptr,
> > boost::scoped_ptr, etc:) should be used.


> Ooh, damn...


> I hoped, I could avoid having to learn something new and 
timeconsuming 
> like boost...


> Isn't there an easier solution without including more libraries?

Most of the smart pointers from boost are in std::tr1 in c++98 and 
std in c++11,
if either std::tr1 or c++11 are supported by your complier. Otherwise 
std::auto_ptr (not recommended, deprecated in c++11) or the boost 
smart pointers should be used.

[toc] | [prev] | [next] | [standalone]


#12959

Fromsomeone <newsboost@gmail.com>
Date2012-01-02 00:47 +0100
Message-ID<4f00f0af$0$286$14726298@news.sunsite.dk>
In reply to#12925
On 12/31/2011 06:35 PM, Garrett Hartshaw wrote:
>> I hoped, I could avoid having to learn something new and
> timeconsuming
>> like boost...
>
>
>> Isn't there an easier solution without including more libraries?
>
> Most of the smart pointers from boost are in std::tr1 in c++98 and std
> in c++11,
> if either std::tr1 or c++11 are supported by your complier. Otherwise
> std::auto_ptr (not recommended, deprecated in c++11) or the boost smart
> pointers should be used.

Ok, damn. I have to learn something new then and spend some time 
understanding that... Only solution I see - thanks a lot for the hint!


[toc] | [prev] | [next] | [standalone]


#12902

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-12-31 09:40 +0000
Message-ID<4efed890$0$2807$7b1e8fa0@news.nbl.fi>
In reply to#12887
someone <newsboost@gmail.com> wrote:
> This, I didn't quite expect, because I thought that at the end of the 
> program, all destructors where guaranteed to be called...

  C++ does not implement garbage collection, which means that if you
allocate an object dynamically with 'new', you'll have to destroy it
explicitly with 'delete'. (Yes, I know that sucks, but either live with
it or switch to C#.)

  If you want the dynamically allocated object to be destroyed automatically
you'll have to use a smart pointer like std::shared_ptr to handle it. In
most cases, though, it's better to avoid the 'new' if you can, and instead
handle objects by value. When an object is handled by value it will be
scope-bound, and thus will be destroyed when its scope ends. In surprisingly
many cases (especially to people accustomed to languages like Java or C#),
you don't need 'new' to handle objects.

[toc] | [prev] | [next] | [standalone]


#12924

Fromsomeone <newsboost@gmail.com>
Date2011-12-31 18:26 +0100
Message-ID<jdngko$7f5$1@dont-email.me>
In reply to#12902
On 12/31/2011 10:40 AM, Juha Nieminen wrote:
> someone<newsboost@gmail.com>  wrote:
>> This, I didn't quite expect, because I thought that at the end of the
>> program, all destructors where guaranteed to be called...
>
>    C++ does not implement garbage collection, which means that if you
> allocate an object dynamically with 'new', you'll have to destroy it
> explicitly with 'delete'. (Yes, I know that sucks, but either live with
> it or switch to C#.)

Ok.

>    If you want the dynamically allocated object to be destroyed automatically
> you'll have to use a smart pointer like std::shared_ptr to handle it. In
> most cases, though, it's better to avoid the 'new' if you can, and instead

I don't think I can avoid it... I have some 20.000 points that needs 
real fast access to screen buffer in opengl application...

I think "new" makes arrays of doubles (or floats) that are stored 
consecutive in memory... I don't think C++ std::vector stores it's 
values, consecutively in memory - does it?

Maybe I'm wrong... I think std::vector has overhead...

> handle objects by value. When an object is handled by value it will be
> scope-bound, and thus will be destroyed when its scope ends. In surprisingly
> many cases (especially to people accustomed to languages like Java or C#),
> you don't need 'new' to handle objects.

Ok, roger...

[toc] | [prev] | [next] | [standalone]


#12926

FromGarrett Hartshaw <ghartshaw@gmail.com>
Date2011-12-31 13:00 -0500
Message-ID<almarsoft.52951692715779568@news.eternal-september.org>
In reply to#12924
On Sat, 31 Dec 2011 18:26:46 +0100, someone <newsboost@gmail.com> 
wrote:
> On 12/31/2011 10:40 AM, Juha Nieminen wrote:
> > someone<newsboost@gmail.com>  wrote:
> >> This, I didn't quite expect, because I thought that at the end 
of the
> >> program, all destructors where guaranteed to be called...
> >
> >    C++ does not implement garbage collection, which means that if 
you
> > allocate an object dynamically with 'new', you'll have to destroy 
it
> > explicitly with 'delete'. (Yes, I know that sucks, but either 
live with
> > it or switch to C#.)


> Ok.


> >    If you want the dynamically allocated object to be destroyed 
automatically
> > you'll have to use a smart pointer like std::shared_ptr to handle 
it. In
> > most cases, though, it's better to avoid the 'new' if you can, 
and instead


> I don't think I can avoid it... I have some 20.000 points that 
needs 
> real fast access to screen buffer in opengl application...


> I think "new" makes arrays of doubles (or floats) that are stored 
> consecutive in memory... I don't think C++ std::vector stores it's 
> values, consecutively in memory - does it?


> Maybe I'm wrong... I think std::vector has overhead...

std::vector is required to store consecutively in memory. &vec[0] 
gives the equivilant C array. std::vector will not help if exit is 
called, as destructors are not called, but will delete its storage 
when a exception is thrown.

> > handle objects by value. When an object is handled by value it 
will be
> > scope-bound, and thus will be destroyed when its scope ends. In 
surprisingly
> > many cases (especially to people accustomed to languages like 
Java or C#),
> > you don't need 'new' to handle objects.


> Ok, roger...

[toc] | [prev] | [next] | [standalone]


#12937

FromNobody <nobody@nowhere.com>
Date2012-01-01 08:57 +0000
Message-ID<pan.2012.01.01.08.57.12.332000@nowhere.com>
In reply to#12924
On Sat, 31 Dec 2011 18:26:46 +0100, someone wrote:

> I don't think I can avoid it... I have some 20.000 points that needs 
> real fast access to screen buffer in opengl application...

?

> I think "new" makes arrays of doubles (or floats) that are stored 
> consecutive in memory... I don't think C++ std::vector stores it's 
> values, consecutively in memory - does it?

It does.

> Maybe I'm wrong... I think std::vector has overhead...

No more so than managing a dynamically-allocated array yourself. If you
know the number of entries in advance, you can use the resize() method to
create all elements. Thereafter, assignment of elements is no slower than
a "raw" array.

std::vector is only slower if you use features which aren't present in a
raw array, e.g. dynamically resizing the array as you add elements.

[toc] | [prev] | [next] | [standalone]


#12958

Fromsomeone <newsboost@gmail.com>
Date2012-01-02 00:43 +0100
Message-ID<4f00ef9a$0$286$14726298@news.sunsite.dk>
In reply to#12937
On 01/01/2012 09:57 AM, Nobody wrote:
> On Sat, 31 Dec 2011 18:26:46 +0100, someone wrote:
>> Maybe I'm wrong... I think std::vector has overhead...
>
> No more so than managing a dynamically-allocated array yourself. If you
> know the number of entries in advance, you can use the resize() method to
> create all elements. Thereafter, assignment of elements is no slower than
> a "raw" array.

Ok, nice to know...

> std::vector is only slower if you use features which aren't present in a
> raw array, e.g. dynamically resizing the array as you add elements.

Ok.

[toc] | [prev] | [next] | [standalone]


#12938

FromJuha Nieminen <nospam@thanks.invalid>
Date2012-01-01 09:03 +0000
Message-ID<4f002163$0$2827$7b1e8fa0@news.nbl.fi>
In reply to#12924
someone <newsboost@gmail.com> wrote:
> I don't think I can avoid it... I have some 20.000 points that needs 
> real fast access to screen buffer in opengl application...

  What exactly does this have to do with derived classes and virtual
destructors?

[toc] | [prev] | [next] | [standalone]


#12960

Fromsomeone <newsboost@gmail.com>
Date2012-01-02 00:49 +0100
Message-ID<4f00f119$0$286$14726298@news.sunsite.dk>
In reply to#12938
On 01/01/2012 10:03 AM, Juha Nieminen wrote:
> someone<newsboost@gmail.com>  wrote:
>> I don't think I can avoid it... I have some 20.000 points that needs
>> real fast access to screen buffer in opengl application...
>
>    What exactly does this have to do with derived classes and virtual
> destructors?

I just don't want static allocation, because only at runtime I know how 
large arrays I need. So I'm saying I need dynamic allocation and I 
cannot avoid that. Then std::vector<> and "new" both have the same 
problem, with no cleaning up if there's an exit() somewhere.

As far as I can see, the solution is that I learn about smart pointers, 
c++11 or std::tr1. And if that fails, I'll look at std::auto_ptr (though 
not recommended from people in here)...

[toc] | [prev] | [next] | [standalone]


#12962

FromLR <lruss@superlink.net>
Date2012-01-01 21:11 -0500
Message-ID<4f0111b5$0$14031$cc2e38e6@news.uslec.net>
In reply to#12960
someone wrote:
> On 01/01/2012 10:03 AM, Juha Nieminen wrote:
>> someone<newsboost@gmail.com>  wrote:
>>> I don't think I can avoid it... I have some 20.000 points that needs
>>> real fast access to screen buffer in opengl application...
>>
>>    What exactly does this have to do with derived classes and virtual
>> destructors?
> 

I downloaded glut and played with it a little. atexit will probably work
for you.

> I just don't want static allocation, because only at runtime I know how 
> large arrays I need. 

How do you find out?



I didn't cut and paste this from working code.

Consider this,

struct SomeData {
    std::vector<glVertex3f> points;
};

// global scope.
SomeData someData;

int main() {

   // there are more efficient ways to do this.
   // but maybe you should see how long this takes
   // before you worry about it.
   someData.points.push_back(glVertex3f(1.,2.,3.)); // or whatever.

   // more stuff here...
   // and then...
   glutMainLoop();
}

Now when glutMainLoop calls exit, someData will be destroyed, and along
with it the memory that points contains.

> So I'm saying I need dynamic allocation and I
> cannot avoid that. Then std::vector<> and "new" both have the same 
> problem, with no cleaning up if there's an exit() somewhere.

I think std::vector is a little easier to deal with.




[toc] | [prev] | [next] | [standalone]


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

Fromsomeone <newsboost@gmail.com>
Date2012-01-02 05:23 +0100
SubjectRe: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND?
Message-ID<4f013125$0$294$14726298@news.sunsite.dk>
In reply to#12962
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 don't think I can avoid it... I have some 20.000 points that needs
>>>> real fast access to screen buffer in opengl application...
>>>
>>>     What exactly does this have to do with derived classes and virtual
>>> destructors?
>>
>
> I downloaded glut and played with it a little. atexit will probably work
> for you.

Wow... I think I just made something much (much?) better!

I really hope you and the other clever guys in here can comment on my 
newly found solution below!

>> I just don't want static allocation, because only at runtime I know how
>> large arrays I need.
>
> How do you find out?

I have some graphical objects and run some code, different from time to 
time, showing different things. Based on what I want the program to 
show, different geometries have to be drawn, requiring different vectors 
of coordinates. I have some code that does a lot based on my input. It 
then tells how large coordinate arrays I need. I then allocate that for 
each geometry. Then I show that. ALSO: Better explanation: See below 
---- bad explanation here, better below...

> I didn't cut and paste this from working code.
>
> Consider this,
>
> struct SomeData {
>      std::vector<glVertex3f>  points;
> };
>
> // global scope.
> SomeData someData;
>
> int main() {
>
>     // there are more efficient ways to do this.
>     // but maybe you should see how long this takes
>     // before you worry about it.
>     someData.points.push_back(glVertex3f(1.,2.,3.)); // or whatever.

Actually my data (coordinates) comes from a fortran program. I link it 
with my c++ (a bit C'ish though) program. I pass a pointer to an array 
of double's for all X + Y + Z-values. I looks like:

----- C++ Program ----
extern "C" {
   void getCoords_(...... const int *maxVectorSize,
    double *cpp_X, double *cpp_Y, double *cpp_Z, int *some_id);
}

bla.bla.
   getCoords_( &someInteger, &someOtherInteger, &maxVectorSize,
			  cpp_X, cpp_Y, cpp_Z, some_id);

====== Fortran Program =====
blabla.

----- C++ Program ----
blabla.


So I don't have the point in a vertex3f, although I'm thinking that I 
can probably do something better than here and only pass 1 
glVertex-coordinate to Fortran...

As you can see: I pass a pointer to the array of double's (maybe I 
should change the fortran-code so it outputs the results as float, which 
is used by opengl)...

>     // more stuff here...
>     // and then...
>     glutMainLoop();
> }
>
> Now when glutMainLoop calls exit, someData will be destroyed, and along
> with it the memory that points contains.

My problem is more complicated than that, but my solution is perfectly 
close to the idea in your suggested solution... I'll show my suggestion 
shortly...

>> So I'm saying I need dynamic allocation and I
>> cannot avoid that. Then std::vector<>  and "new" both have the same
>> problem, with no cleaning up if there's an exit() somewhere.
>
> I think std::vector is a little easier to deal with.

Maybe... I'm just a little bit stupid and afraid. So...

In my case: Using std::vector, would still allow me to pass a pointer to 
arrays (of double or float) into a Fortran90 subroutine, which needs 
pointers to the data so it can store the results... Is there any 
problems here with std::vector???

What do you think?


======== here's my possible solution, please give some input ========
First: Short explanation... I have a class: drawableObj (base class) 
from which all different geometries iherit.

As an example, I have a gear class that inherits from drawableObj. 
Problem: Currently I only have a gear-class but later I want to have 
other geometrical classes deriving from base class drawableObj, e.g. 
maybe introduce a connecting "shaft"-class + a foundation + maybe sun + 
stars + skyes + landscape etc. etc (all graphical objects derive from 
base class drawableObj)...

I made it this way, because I wanted to introduce polymorphism in my 
display()-function of my program... This makes it *REALLY* easy to 
add/remove objects... See below... Enough introduction...


--- main.cpp ---
drawableObj allObjs; // must be global!

void display()
{
   glClear(GL_COLOR_BUFFER_BIT);
   ...
   // UPDATE ALL GRAPHICAL OBJS...
   for (int z=0; z<(int) drawableObj::pObjs.size(); z++)
	{
	  glPushMatrix();
	  ((gearClass*) drawableObj::pObjs[z])->updateDisplay();
	  glPopMatrix();
	}
   ..
   glutSwapBuffers(); // also does glFlush();
}

int main(int argc, char** argv)
{
   drawableObj *testGearPtr =
	new gearClass( .... ); // rotSpeed etc, etc... bla.bla

   drawableObj *testGearPtr2 =
	new gearClass( .... ); // rotSpeed etc, etc... bla.bla

   // Calculate INITIAL X+Y+Z points (only done once!)
   for (int z=0; z<(int) drawableObj::pObjs.size(); z++)
	{
	  ((gearClass*) drawableObj::pObjs[z])->callFortran();
	}

   // ******* OpenGL starting... *******
   glutInit(&argc, argv);
   .... bla bla...

   glutMainLoop(); // exits directly to OS from here...

   return(0); // never comes here - just to satisfy compiler...
}





--- helper.h (#include guard not shown) ---
class drawableObj
{
  // private: // protected: // I don't have anything here

  public:
   // global+static pointer to all GRAPHICAL objs:
   static vector<drawableObj*> pObjs;

   drawableObj(); // constructor

   // destructor
   virtual ~drawableObj();

   // member functions
   virtual void draw(); // <---used in openGL display loop
   void showNumObjs();
   void test();
};





--- gearClass.h (#include guard not shown) ---
class gearClass : public drawableObj
{
private:

public:
   bool memAllocated; // IMPORTANT TO KNOW IF DELETE HAS BEEN CALLED
   double *cpp_X, *cpp_Y, *cpp_Z;
   bla bla...

   virtual ~gearClass(); // destructor

   // member functions
   void deAllocate();
   void callFortran();
   void updateDisplay();
   bla.bla
};





--- helper.cpp ---
#include "helper.h"
#include "gearClass.h" // for knowing "gearClass"-type

// NOT SURE ABOUT THIS, BUT COMPILER COMPLAINS IF NOT "EXTERN"...
extern vector<drawableObj*> drawableObj::pObjs;


drawableObj::~drawableObj() // destructor
{
   int numObj = pObjs.size();
   if (numObj == 0)
	cout << "   Destructing base (drawableObj), " <<
	  "no objects left:  #objects: " <<
	numObj << endl << endl;
   else
	{
	  cout << endl << "---- NB: BASE IS BEING DESTROYED, " <<
		"BUT DERIVED OBJECTS MUST ALSO DIE ----" << endl;
	  int numObjs = (int) drawableObj::pObjs.size();
	  cout << "---- Number of obj's to delete: " << numObjs <<
		" ----" << endl;
	  for (int z=0; z<numObjs; z++)
		{
		  if ( ((gearClass*) drawableObj::pObjs[z])->memAllocated )
		   delete ((gearClass*) drawableObj::pObjs[z]);
		}
	}
}





--- gearClass.cpp ---
gearClass::gearClass() // constructor
{
   drawableObj::pObjs.push_back((gearClass*) this); // ISN'T THIS NICE ??
   ... bla bla...

   cpp_X = new double[maxVectorSize]; // NEEDS TO BE FREE'd BY DESTRUCTOR
   cpp_Y = new double[maxVectorSize]; // NEEDS TO BE FREE'd BY DESTRUCTOR
   cpp_Z = new double[maxVectorSize]; // NEEDS TO BE FREE'd BY DESTRUCTOR
   memAllocated = true; // need to know if allocated or not...
}

gearClass::~gearClass() // destructor
{
   if (memAllocated)
	{
	  deAllocate();
	  drawableObj::pObjs.pop_back(); // REMOVE 1 COUNT...
	  cout << "Derived: gearClass::~gearClass() has free'd memory..." << endl;
	  memAllocated = false;
	}
}

void gearClass::deAllocate()
{
   cout << "   (deallocating cpp_X, cpp_Y and cpp_Kontur_id)" << endl;
   delete [] cpp_X;
   delete [] cpp_Y;
   delete [] cpp_Z;
}


======== that was possible solution, please give some input ========

Final remarks:

This code seem to clean up everything, by calling the destructors and 
de-allocating correcty (because I have the global drawableObj allObjs in 
top of main(), I think - isn't that right?)... Even if I use exit(0) or 
exit(1), it cleans up, I think... Please tell me if I've made any error 
somewhere, that I haven't seen... Also please write suggestions, if 
something can be improved in ANY way!

Thank you, all! :-)

[toc] | [prev] | [next] | [standalone]


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

FromGarrett Hartshaw <ghartshaw@gmail.com>
Date2012-01-02 00:14 -0500
SubjectRe: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND?
Message-ID<almarsoft.4514077305606493745@news.eternal-september.org>
In reply to#12966
On Mon, 02 Jan 2012 05:23:01 +0100, someone <newsboost@gmail.com> 
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 don't think I can avoid it... I have some 20.000 points that 
needs
> >>>> real fast access to screen buffer in opengl application...
> >>>
> >>>     What exactly does this have to do with derived classes and 
virtual
> >>> destructors?
> >>
> >
> > I downloaded glut and played with it a little. atexit will 
probably work
> > for you.


> Wow... I think I just made something much (much?) better!


> I really hope you and the other clever guys in here can comment on 
my 
> newly found solution below!


> >> I just don't want static allocation, because only at runtime I 
know how
> >> large arrays I need.
> >
> > How do you find out?


> I have some graphical objects and run some code, different from 
time to 
> time, showing different things. Based on what I want the program to 
> show, different geometries have to be drawn, requiring different 
vectors 
> of coordinates. I have some code that does a lot based on my input. 
It 
> then tells how large coordinate arrays I need. I then allocate that 
for 
> each geometry. Then I show that. ALSO: Better explanation: See 
below 
> ---- bad explanation here, better below...


> > I didn't cut and paste this from working code.
> >
> > Consider this,
> >
> > struct SomeData {
> >      std::vector<glVertex3f>  points;
> > };
> >
> > // global scope.
> > SomeData someData;
> >
> > int main() {
> >
> >     // there are more efficient ways to do this.
> >     // but maybe you should see how long this takes
> >     // before you worry about it.
> >     someData.points.push_back(glVertex3f(1.,2.,3.)); // or 
whatever.


> Actually my data (coordinates) comes from a fortran program. I link 
it 
> with my c++ (a bit C'ish though) program. I pass a pointer to an 
array 
> of double's for all X + Y + Z-values. I looks like:


> ----- C++ Program ----
> extern "C" {
>    void getCoords_(...... const int *maxVectorSize,
>     double *cpp_X, double *cpp_Y, double *cpp_Z, int *some_id);
> }


> bla.bla.
>    getCoords_( &someInteger, &someOtherInteger, &maxVectorSize,
> 			  cpp_X, cpp_Y, cpp_Z, some_id);


> ====== Fortran Program =====
> blabla.


> ----- C++ Program ----
> blabla.




> So I don't have the point in a vertex3f, although I'm thinking that 
I 
> can probably do something better than here and only pass 1 
> glVertex-coordinate to Fortran...


> As you can see: I pass a pointer to the array of double's (maybe I 
> should change the fortran-code so it outputs the results as float, 
which 
> is used by opengl)...


> >     // more stuff here...
> >     // and then...
> >     glutMainLoop();
> > }
> >
> > Now when glutMainLoop calls exit, someData will be destroyed, and 
along
> > with it the memory that points contains.


> My problem is more complicated than that, but my solution is 
perfectly 
> close to the idea in your suggested solution... I'll show my 
suggestion 
> shortly...


> >> So I'm saying I need dynamic allocation and I
> >> cannot avoid that. Then std::vector<>  and "new" both have the 
same
> >> problem, with no cleaning up if there's an exit() somewhere.
> >
> > I think std::vector is a little easier to deal with.


> Maybe... I'm just a little bit stupid and afraid. So...


> In my case: Using std::vector, would still allow me to pass a 
pointer to 
> arrays (of double or float) into a Fortran90 subroutine, which 
needs 
> pointers to the data so it can store the results... Is there any 
> problems here with std::vector???


> What do you think?




> ======== here's my possible solution, please give some input 
========
> First: Short explanation... I have a class: drawableObj (base 
class) 
> from which all different geometries iherit.


> As an example, I have a gear class that inherits from drawableObj. 
> Problem: Currently I only have a gear-class but later I want to 
have 
> other geometrical classes deriving from base class drawableObj, 
e.g. 
> maybe introduce a connecting "shaft"-class + a foundation + maybe 
sun + 
> stars + skyes + landscape etc. etc (all graphical objects derive 
from 
> base class drawableObj)...


> I made it this way, because I wanted to introduce polymorphism in 
my 
> display()-function of my program... This makes it *REALLY* easy to 
> add/remove objects... See below... Enough introduction...




> --- main.cpp ---
> drawableObj allObjs; // must be global!


> void display()
> {
>    glClear(GL_COLOR_BUFFER_BIT);
>    ...
>    // UPDATE ALL GRAPHICAL OBJS...
>    for (int z=0; z<(int) drawableObj::pObjs.size(); z++)
> 	{
> 	  glPushMatrix();
> 	  ((gearClass*) drawableObj::pObjs[z])->updateDisplay();
> 	  glPopMatrix();
> 	}
>    ..
>    glutSwapBuffers(); // also does glFlush();
> }


> int main(int argc, char** argv)
> {
>    drawableObj *testGearPtr =
> 	new gearClass( .... ); // rotSpeed etc, etc... bla.bla


>    drawableObj *testGearPtr2 =
> 	new gearClass( .... ); // rotSpeed etc, etc... bla.bla


>    // Calculate INITIAL X+Y+Z points (only done once!)
>    for (int z=0; z<(int) drawableObj::pObjs.size(); z++)
> 	{
> 	  ((gearClass*) drawableObj::pObjs[z])->callFortran();
> 	}


>    // ******* OpenGL starting... *******
>    glutInit(&argc, argv);
>    .... bla bla...


>    glutMainLoop(); // exits directly to OS from here...


>    return(0); // never comes here - just to satisfy compiler...
> }










> --- helper.h (#include guard not shown) ---
> class drawableObj
> {
>   // private: // protected: // I don't have anything here


>   public:
>    // global+static pointer to all GRAPHICAL objs:
>    static vector<drawableObj*> pObjs;


>    drawableObj(); // constructor


>    // destructor
>    virtual ~drawableObj();


>    // member functions
>    virtual void draw(); // <---used in openGL display loop
>    void showNumObjs();
>    void test();
> };










> --- gearClass.h (#include guard not shown) ---
> class gearClass : public drawableObj
> {
> private:


> public:
>    bool memAllocated; // IMPORTANT TO KNOW IF DELETE HAS BEEN CALLED
>    double *cpp_X, *cpp_Y, *cpp_Z;
>    bla bla...


>    virtual ~gearClass(); // destructor


>    // member functions
>    void deAllocate();
>    void callFortran();
>    void updateDisplay();
>    bla.bla
> };










> --- helper.cpp ---
> #include "helper.h"
> #include "gearClass.h" // for knowing "gearClass"-type


> // NOT SURE ABOUT THIS, BUT COMPILER COMPLAINS IF NOT "EXTERN"...
> extern vector<drawableObj*> drawableObj::pObjs;




> drawableObj::~drawableObj() // destructor
> {
>    int numObj = pObjs.size();
>    if (numObj == 0)
> 	cout << "   Destructing base (drawableObj), " <<
> 	  "no objects left:  #objects: " <<
> 	numObj << endl << endl;
>    else
> 	{
> 	  cout << endl << "---- NB: BASE IS BEING DESTROYED, " <<
> 		"BUT DERIVED OBJECTS MUST ALSO DIE ----" << endl;
> 	  int numObjs = (int) drawableObj::pObjs.size();
> 	  cout << "---- Number of obj's to delete: " << numObjs <<
> 		" ----" << endl;
> 	  for (int z=0; z<numObjs; z++)
> 		{
> 		  if ( ((gearClass*) drawableObj::pObjs[z])->memAllocated )
> 		   delete ((gearClass*) drawableObj::pObjs[z]);
> 		}
> 	}
> }










> --- gearClass.cpp ---
> gearClass::gearClass() // constructor
> {
>    drawableObj::pObjs.push_back((gearClass*) this); // ISN'T THIS 
NICE ??
>    ... bla bla...


>    cpp_X = new double[maxVectorSize]; // NEEDS TO BE FREE'd BY 
DESTRUCTOR
>    cpp_Y = new double[maxVectorSize]; // NEEDS TO BE FREE'd BY 
DESTRUCTOR
>    cpp_Z = new double[maxVectorSize]; // NEEDS TO BE FREE'd BY 
DESTRUCTOR
>    memAllocated = true; // need to know if allocated or not...
> }


> gearClass::~gearClass() // destructor
> {
>    if (memAllocated)
> 	{
> 	  deAllocate();
> 	  drawableObj::pObjs.pop_back(); // REMOVE 1 COUNT...
> 	  cout << "Derived: gearClass::~gearClass() has free'd memory..." 
<< endl;
> 	  memAllocated = false;
> 	}
> }


> void gearClass::deAllocate()
> {
>    cout << "   (deallocating cpp_X, cpp_Y and cpp_Kontur_id)" << 
endl;
>    delete [] cpp_X;
>    delete [] cpp_Y;
>    delete [] cpp_Z;
> }




> ======== that was possible solution, please give some input ========


> Final remarks:


> This code seem to clean up everything, by calling the destructors 
and 
> de-allocating correcty (because I have the global drawableObj 
allObjs in 
> top of main(), I think - isn't that right?)... Even if I use 
exit(0) or 
> exit(1), it cleans up, I think... Please tell me if I've made any 
error 
> somewhere, that I haven't seen... Also please write suggestions, if 
> something can be improved in ANY way!


> Thank you, all! :-)

If you make cpp_X, etc. std::vector<double> instead of double * you 
can get rid of your deAllocate function. just replace the 'new 
double[size]' with 'vector<double>( size )' in you constructor, and 
use '&vec[0]' instead of 'vec' to pass to a function requiring the 
data as a double *. Otherwise I think that it should work (I think 
the destructors of static functions are registered with atexit behind 
the scenes, but I am not positive. You woul.d need to register the 
destructors manually with atexit if this is not the case.)

[toc] | [prev] | [next] | [standalone]


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

Fromsomeone <newsboost@gmail.com>
Date2012-01-02 17:55 +0100
SubjectRe: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND?
Message-ID<4f01e192$0$285$14726298@news.sunsite.dk>
In reply to#12970
On 01/02/2012 06:14 AM, Garrett Hartshaw wrote:
> On Mon, 02 Jan 2012 05:23:01 +0100, someone <newsboost@gmail.com> wrote:
>> On 01/02/2012 03:11 AM, LR wrote:

>> exit(1), it cleans up, I think... Please tell me if I've made any
> error
>> somewhere, that I haven't seen... Also please write suggestions, if
>> something can be improved in ANY way!
>
>
>> Thank you, all! :-)
>
> If you make cpp_X, etc. std::vector<double> instead of double * you can
> get rid of your deAllocate function. just replace the 'new double[size]'
> with 'vector<double>( size )' in you constructor, and use '&vec[0]'
> instead of 'vec' to pass to a function requiring the data as a double *.

Ok, roger I'll try that a bit later (in a few hours) and get back if any 
problems/questions arise, thanks (the calling Fortran part made me think 
that it wouldn't work, but I guess you're probably right and that I have 
to see for myself :-) )!

> Otherwise I think that it should work (I think the destructors of static
> functions are registered with atexit behind the scenes, but I am not
> positive. You woul.d need to register the destructors manually with
> atexit if this is not the case.)

Ok, got it. Thank you very much - am a bit tired now, but will try it in 
a few hours :-)

[toc] | [prev] | [next] | [standalone]


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

Fromsomeone <newsboost@gmail.com>
Date2012-01-02 22:17 +0100
SubjectRe: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND?
Message-ID<4f021ed8$0$292$14726298@news.sunsite.dk>
In reply to#12970
On 01/02/2012 06:14 AM, Garrett Hartshaw wrote:
>> Thank you, all! :-)
>
> If you make cpp_X, etc. std::vector<double> instead of double * you can
> get rid of your deAllocate function. just replace the 'new double[size]'
> with 'vector<double>( size )' in you constructor, and use '&vec[0]'
> instead of 'vec' to pass to a function requiring the data as a double *.

Ok... Now I did it... However, I'm not sure there's any difference at 
all... I mean: Now I have:

--- header file ---
   std::vector<double> cpp_X, cpp_Y, cpp_Z;

--- c++ file ---
   cpp_X.resize( maxVectorSize ); // new double[maxVectorSize];
   cpp_Y.resize( maxVectorSize ); // new double[maxVectorSize];
   cpp_Z.resize( maxVectorSize ); // new double[maxVectorSize];

I modified my deAllocate slightly:
void gearClass::deAllocate()
{
   cpp_X.clear();
   cpp_Y.clear();
   cpp_Z.clear();
   cout << "   (deallocating)" << endl;
}

However: How can I convince myself that deAllocate is un-neccessary in 
either case, using either std::vector for cpp_X, cpp_Y and cpp_Z ?

In my naive opionion, using std::vector makes no difference at all... In 
all cases, I actually think the deAllocate() function is not strictly 
necessary because the OS would cleanup in either case. However, I'm 
happy I did it - 2 reasons:

1) Better to clean up in any cases - just better programming practice, I 
think.
2) Using std::vector is more "the C++-way" compared to the usual 
"C-methods" that I tend to use, because I'm maybe slightly more familiar 
with C than C++ (however, my skills are improving now).

> Otherwise I think that it should work (I think the destructors of static
> functions are registered with atexit behind the scenes, but I am not
> positive. You woul.d need to register the destructors manually with
> atexit if this is not the case.)

You mean the destructors for std::vector, right?

How do I know whether or not destructors for std::vector has/is been 
called with my current code (based on your suggestion) ?

With my own destructors, it wasn't that complicated to add some 
cout-statements, as I could program the destructor myself. This is 
however, not the case for std::vector destructors - I don't know how 
these destructors look like at all...

[toc] | [prev] | [next] | [standalone]


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

FromGarrett Hartshaw <ghartshaw@gmail.com>
Date2012-01-02 16:40 -0500
SubjectRe: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND?
Message-ID<almarsoft.7014165946754704252@news.eternal-september.org>
In reply to#12996
On Mon, 02 Jan 2012 22:17:12 +0100, someone <newsboost@gmail.com> 
wrote:
> On 01/02/2012 06:14 AM, Garrett Hartshaw wrote:
> >> Thank you, all! :-)
> >
> > If you make cpp_X, etc. std::vector<double> instead of double * 
you can
> > get rid of your deAllocate function. just replace the 'new 
double[size]'
> > with 'vector<double>( size )' in you constructor, and use 
'&vec[0]'
> > instead of 'vec' to pass to a function requiring the data as a 
double *.


> Ok... Now I did it... However, I'm not sure there's any difference 
at 
> all... I mean: Now I have:


> --- header file ---
>    std::vector<double> cpp_X, cpp_Y, cpp_Z;


> --- c++ file ---
>    cpp_X.resize( maxVectorSize ); // new double[maxVectorSize];
>    cpp_Y.resize( maxVectorSize ); // new double[maxVectorSize];
>    cpp_Z.resize( maxVectorSize ); // new double[maxVectorSize];


> I modified my deAllocate slightly:
> void gearClass::deAllocate()
> {
>    cpp_X.clear();
>    cpp_Y.clear();
>    cpp_Z.clear();
>    cout << "   (deallocating)" << endl;
> }


> However: How can I convince myself that deAllocate is un-neccessary 
in 
> either case, using either std::vector for cpp_X, cpp_Y and cpp_Z ?


> In my naive opionion, using std::vector makes no difference at 
all... In 
> all cases, I actually think the deAllocate() function is not 
strictly 
> necessary because the OS would cleanup in either case. However, I'm 
> happy I did it - 2 reasons:

yes, if you don't use push_back, etc... the std::vector is pretty 
much the same (except for the need to call delete).

> 1) Better to clean up in any cases - just better programming 
practice, I 
> think.
> 2) Using std::vector is more "the C++-way" compared to the usual 
> "C-methods" that I tend to use, because I'm maybe slightly more 
familiar 
> with C than C++ (however, my skills are improving now).


> > Otherwise I think that it should work (I think the destructors of 
static
> > functions are registered with atexit behind the scenes, but I am 
not
> > positive. You woul.d need to register the destructors manually 
with
> > atexit if this is not the case.)


> You mean the destructors for std::vector, right?


> How do I know whether or not destructors for std::vector has/is 
been 
> called with my current code (based on your suggestion) ?


> With my own destructors, it wasn't that complicated to add some 
> cout-statements, as I could program the destructor myself. This is 
> however, not the case for std::vector destructors - I don't know 
how 
> these destructors look like at all...

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.

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

[toc] | [prev] | [next] | [standalone]


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

Fromsomeone <newsboost@gmail.com>
Date2012-01-03 00:48 +0100
SubjectRe: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND?
Message-ID<4f02424b$0$294$14726298@news.sunsite.dk>
In reply to#12998
On 01/02/2012 10:40 PM, Garrett Hartshaw wrote:
> On Mon, 02 Jan 2012 22:17:12 +0100, someone <newsboost@gmail.com> wrote:
>> On 01/02/2012 06:14 AM, Garrett Hartshaw wrote:
...
>> With my own destructors, it wasn't that complicated to add some
>> cout-statements, as I could program the destructor myself. This is
>> however, not the case for std::vector destructors - I don't know
> how
>> these destructors look like at all...
>
> 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..

[toc] | [prev] | [next] | [standalone]


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

FromLR <lruss@superlink.net>
Date2012-01-02 14:47 -0500
SubjectRe: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND?
Message-ID<4f020923$0$11917$cc2e38e6@news.uslec.net>
In reply to#12966
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)
----------------------------------

[toc] | [prev] | [next] | [standalone]


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

Fromsomeone <newsboost@gmail.com>
Date2012-01-03 00:43 +0100
SubjectRe: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND?
Message-ID<4f024132$0$294$14726298@news.sunsite.dk>
In reply to#12989
On 01/02/2012 08:47 PM, LR wrote:
> 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.

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

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

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?

>>     // ******* 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.

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

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

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)


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

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;

>> {
>> private:
>>
>> public:
>>     bool memAllocated; // IMPORTANT TO KNOW IF DELETE HAS BEEN CALLED
> Use std::vector and this problem doesn't arise.

Ok.

>> #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.

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();
	}
   ....
}


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

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

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


>> ======== 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.

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::objects’, 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::objects’, 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::objects’, which is of non-class type 
‘const DrawObjectsContainer {aka const int}’
test.cpp:76:33: error: expected ‘)’ before ‘;’ token

>                      i++) {

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



[toc] | [prev] | [next] | [standalone]


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

FromLR <lruss@superlink.net>
Date2012-01-02 20:30 -0500
SubjectRe: noob question - destructors - freeing memory... POSSIBLE SOLUTION FOUND?
Message-ID<4f0259b0$0$25811$cc2e38e6@news.uslec.net>
In reply to#13010
someone wrote:
> On 01/02/2012 08:47 PM, LR wrote:
>> someone wrote:
>>> On 01/02/2012 03:11 AM, LR wrote:
>>>> someone wrote:

> (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*)?



>>>     return(0); // never comes here - just to satisfy compiler...
>>
>> Odd, because it shouldn't be required at all.
> 
> 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?

>>> 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?
> 
> 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.

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


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

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.



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

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.



[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | comp.lang.c++


csiph-web