Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > lifetime of static objects

Reply
Thread Tools

lifetime of static objects

 
 
Simon Elliott
Guest
Posts: n/a
 
      10-11-2004
Consider the following, incorrect, code:


#pragma hdrstop
#include <condefs.h>
#include <iostream>
#include <conio.h>

class bar
{
private:
operator = (const bar&);
bar(const bar&);
public:
bar(void)
{
cout << "bar: constructor " << std::endl;
}
~bar()
{
cout << "bar: destructor" << std::endl;
}
void Hello(int thing)
{
cout << "bar: say hello " << thing << std::endl;
}
void Goodbye(int thing)
{
cout << "bar: wave goodbye " << thing << std::endl;
}
};


class foo
{
private:
int thing_;
foo();
operator = (const foo&);
foo(const foo&);
static bar &instance()
{
static bar theInstance;
return theInstance;
}
public:
explicit foo(int thing):thing_(thing)
{
cout << "foo: constructor " << thing_ << std::endl;
bar& the_bar = instance();
the_bar.Hello(thing_);
}
~foo()
{
bar& the_bar = instance();
the_bar.Goodbye(thing_);
cout << "foo: destructor " << thing_ << std::endl;
}
};

static foo foo1(1);
static foo foo2(2);

int main(int argc, char **argv)
{
return 0;
}

The output from this is:

foo: constructor 1
bar: constructor
bar: say hello 1
foo: constructor 2
bar: say hello 2
bar: destructor
bar: wave goodbye 2
foo: destructor 2
bar: wave goodbye 1
foo: destructor 1

Which isn't what's required: methods in the static instance of bar are
being called after bar's destructor has been called.

How would I change the code to make sure that the static instance of
bar is destroyed last?

--
Simon Elliott http://www.ctsn.co.uk
 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      10-11-2004
Simon Elliott wrote:

> Consider the following, incorrect, code:
>
>
> #pragma hdrstop
> #include <condefs.h>
> #include <iostream>
> #include <conio.h>
>
> class bar
> {
> private:
> operator = (const bar&);
> bar(const bar&);
> public:
> bar(void)
> {
> cout << "bar: constructor " << std::endl;
> }
> ~bar()
> {
> cout << "bar: destructor" << std::endl;
> }
> void Hello(int thing)
> {
> cout << "bar: say hello " << thing << std::endl;
> }
> void Goodbye(int thing)
> {
> cout << "bar: wave goodbye " << thing << std::endl;
> }
> };
>
>
> class foo
> {
> private:
> int thing_;
> foo();
> operator = (const foo&);
> foo(const foo&);
> static bar &instance()
> {
> static bar theInstance;
> return theInstance;
> }
> public:
> explicit foo(int thing):thing_(thing)
> {
> cout << "foo: constructor " << thing_ << std::endl;
> bar& the_bar = instance();
> the_bar.Hello(thing_);
> }
> ~foo()
> {
> bar& the_bar = instance();
> the_bar.Goodbye(thing_);
> cout << "foo: destructor " << thing_ << std::endl;
> }
> };
>
> static foo foo1(1);
> static foo foo2(2);
>
> int main(int argc, char **argv)
> {
> return 0;
> }
>
> The output from this is:
>
> foo: constructor 1
> bar: constructor
> bar: say hello 1
> foo: constructor 2
> bar: say hello 2
> bar: destructor
> bar: wave goodbye 2
> foo: destructor 2
> bar: wave goodbye 1
> foo: destructor 1
>
> Which isn't what's required: methods in the static instance of bar are
> being called after bar's destructor has been called.
>
> How would I change the code to make sure that the static instance of
> bar is destroyed last?


You have to create it first. Pull the 'static bar theInstance' from
the function and place it in the file scope (without 'static') before
the other two objects. BTW, you didn't need "static" for them either,
unless you don't want them to be visible from other modules.

Victor
 
Reply With Quote
 
 
 
 
Simon Elliott
Guest
Posts: n/a
 
      10-11-2004
On 11/10/2004, Victor Bazarov wrote:

> How would I change the code to make sure that the static instance of
> > bar is destroyed last?

>
> You have to create it first. Pull the 'static bar theInstance' from
> the function and place it in the file scope (without 'static') before
> the other two objects.


That would make the objects harder to use. I want people to be able to
use a foo without thinking about a bar. (I'd like to be able to remove
all visibility of bar from my foo definition, but I suspect that's a
bridge too far.)


--
Simon Elliott http://www.ctsn.co.uk
 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      10-11-2004

>
> How would I change the code to make sure that the static instance of
> bar is destroyed last?
>


Destruction is always in reverse order of construction. So the only way to
ensure that bar is destroyed last is to construct it first.

john


 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      10-11-2004
* "Simon Elliott" <Simon at ctsn.co.uk>:
> Consider the following, incorrect, code:
>
>
> #pragma hdrstop
> #include <condefs.h>
> #include <iostream>
> #include <conio.h>
>
> class bar
> {
> private:
> operator = (const bar&);
> bar(const bar&);
> public:
> bar(void)
> {
> cout << "bar: constructor " << std::endl;
> }
> ~bar()
> {
> cout << "bar: destructor" << std::endl;
> }
> void Hello(int thing)
> {
> cout << "bar: say hello " << thing << std::endl;
> }
> void Goodbye(int thing)
> {
> cout << "bar: wave goodbye " << thing << std::endl;
> }
> };
>
>
> class foo
> {
> private:
> int thing_;
> foo();
> operator = (const foo&);
> foo(const foo&);
> static bar &instance()
> {
> static bar theInstance;
> return theInstance;
> }
> public:
> explicit foo(int thing):thing_(thing)
> {
> cout << "foo: constructor " << thing_ << std::endl;
> bar& the_bar = instance();
> the_bar.Hello(thing_);
> }
> ~foo()
> {
> bar& the_bar = instance();
> the_bar.Goodbye(thing_);
> cout << "foo: destructor " << thing_ << std::endl;
> }
> };
>
> static foo foo1(1);
> static foo foo2(2);
>
> int main(int argc, char **argv)
> {
> return 0;
> }
>
> The output from this is:
>
> foo: constructor 1
> bar: constructor
> bar: say hello 1
> foo: constructor 2
> bar: say hello 2
> bar: destructor
> bar: wave goodbye 2
> foo: destructor 2
> bar: wave goodbye 1
> foo: destructor 1
>
> Which isn't what's required: methods in the static instance of bar are
> being called after bar's destructor has been called.
>
> How would I change the code to make sure that the static instance of
> bar is destroyed last?


The only sure way (i.e. without imposing "invisible" restrictions on usage)
would be to make bar instance reference counted. I think. You can find
an example of that idea in Andrei Alexandrescu's "Modern C++ Design".

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
 
Reply With Quote
 
DaKoadMunky
Guest
Posts: n/a
 
      10-11-2004
>Destruction is always in reverse order of construction. So the only way to
>ensure that bar is destroyed last is to construct it first.


Isn't that order based not on the order in which constructors were called but
the order in which constructors were completed?

In the OP's case the constructor for Foo is called first but the constructor
for Bar completes before the Foo constructor therefore the Bar destructor
should be called last because it was the first fully constructed object.

Not having the standard I can't provide support for this, but I did see it
discussed elsewhere on the net and the example code posted was virtually
identical to the OP's.








 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      10-12-2004

"DaKoadMunky" <> wrote in message
news:...
> >Destruction is always in reverse order of construction. So the only way
> >to
>>ensure that bar is destroyed last is to construct it first.

>
> Isn't that order based not on the order in which constructors were called
> but
> the order in which constructors were completed?
>
> In the OP's case the constructor for Foo is called first but the
> constructor
> for Bar completes before the Foo constructor therefore the Bar destructor
> should be called last because it was the first fully constructed object.
>
> Not having the standard I can't provide support for this, but I did see it
> discussed elsewhere on the net and the example code posted was virtually
> identical to the OP's.
>


You are right, 3.6.3 para 1 says that destructors are called in reverse
order of the completion of their constructor calls.

Looks like the OP's compiler is not implementing this correctly.

john


 
Reply With Quote
 
Simon Elliott
Guest
Posts: n/a
 
      10-12-2004
On 12/10/2004, John Harrison wrote:
> > Isn't that order based not on the order in which constructors were
> > called but
> > the order in which constructors were completed?
> >
> > In the OP's case the constructor for Foo is called first but the
> > constructor
> > for Bar completes before the Foo constructor therefore the Bar
> > destructor should be called last because it was the first fully
> > constructed object.
> >
> > Not having the standard I can't provide support for this, but I did
> > see it discussed elsewhere on the net and the example code posted
> > was virtually identical to the OP's.
> >

>
> You are right, 3.6.3 para 1 says that destructors are called in
> reverse order of the completion of their constructor calls.
>
> Looks like the OP's compiler is not implementing this correctly.


That's entirely possible since it's BCB3 which is quite old.

But with BCB6 I get this:

foo: constructor 1
bar: constructor
bar: say hello 1
foo: constructor 2
bar: say hello 2
bar: destructor
bar: constructor
bar: wave goodbye 2
foo: destructor 2
bar: wave goodbye 1
foo: destructor 1

As you can see, bar is destroyed and then rebuilt. And then not
destroyed second time round. That doesn't seem right to me.

When I've got the chance I'll try this on gcc on my hosting provider's
unix box.

--
Simon Elliott http://www.ctsn.co.uk
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
lifetime of objects (here: strings) Stefan Ram C++ 14 04-13-2009 09:44 AM
class objects, method objects, function objects 7stud Python 11 03-20-2007 06:05 PM
Lifetime of static member variable in ASP.NET Vagif Abilov ASP .Net 3 05-24-2006 06:57 PM
lifetime of ASP objects Elie Grouchko ASP General 0 05-22-2005 04:36 PM
Lifetime of static objects revisited Simon Elliott C++ 5 12-04-2004 10:16 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57