engeln@danetis.UUCP (Werner Engeln) (11/22/90)
To ensure that global objects of a library is initialized befor its first
use, I implemented a counter to maintain the number of translation units
using it (see "the annotated C++ reference manual section 3.4, Ellis &
Stroustrup).[example below]
To my confusion, my library objects are constructed (and destructed) twice !
How can I reduce constructor calls to only ONE for each global object ??
mail, and I will post a summary
engeln@danetis.uucp
------------------------------- cut here -- nifty_library.h -----------
// nifty_library.h
#ifndef nifty_h
#define nifty_h
class foo {
public :
foo (const char *);
~foo ();
void print ();
private :
const char * name;
};
class nifty_counter {
public :
nifty_counter ();
~nifty_counter ();
private :
static count;
};
#ifndef nifty_cc
// global objects
extern foo aFoo;
// counter of translation units
static nifty_counter nifty;
#endif nifty_cc
#endif nifty_h
------------------------------- cut here -- nifty_library.cc ----------
#define nifty_cc
extern "C" void printf (const char *, ...);
// declare global objects to resolve external references
foo aFoo ("aFoo by library startup");
// memberfunctions
foo::foo (const char * c)
: name (c)
{
printf ("constructing %s\n", name);
}
foo::~foo ()
{
printf ("destructing %s\n", name);
}
void foo::print ()
{
printf ("foo named %s\n", name);
}
// counter implementation
nifty_counter::nifty_counter ()
{
if (count++ == 0) {
// initialize global objects
aFoo.foo ("aFoo by nifty_counter");
}
}
nifty_counter::~nifty_counter ()
{
if (--count == 0) {
// clean up global objects
aFoo.foo::~foo ();
}
}
------------------------------- cut here -- nifty_user.cc -------------
#include "nifty.h"
void main ()
{
aFoo.print ();
}
------------------------------- cut here -- output --------------------
constructing aFoo by nifty_counter
constructing aFoo by library startup
foo named aFoo by library startup
destructing aFoo by library startup
destructing aFoo by library startup
--
Werner Engeln Phone: +49-711/736051 FAX: +49-711/736054
Danet-IS GmbH UUCP: engeln@danetis.uucp
Waldburgstrasse 17 - 19 BITNET: engeln%danetis.uucp@unido.bitnet
D-7000 Stuttgart 80 X.400: C=DE;A=DBP;P=DANET;O=IS;S=Engelnrmartin@clear.com (Bob Martin) (11/28/90)
I am posting this because your mail bounced... In article <3306@danetis.UUCP> you write: >To ensure that global objects of a library is initialized befor its first >use, I implemented a counter to maintain the number of translation units >using it (see "the annotated C++ reference manual section 3.4, Ellis & >Stroustrup).[example below] >To my confusion, my library objects are constructed (and destructed) twice ! >How can I reduce constructor calls to only ONE for each global object ?? > >mail, and I will post a summary > >engeln@danetis.uucp >------------------------------- cut here -- nifty_library.h ----------- >..... junk taken out ..... > >// counter of translation units >static nifty_counter nifty; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This constructs nifty. The constructor for nifty explicity calls the constructor for foo. That is the cause of the first aFoo construction by nifty. > >#endif nifty_cc >#endif nifty_h >------------------------------- cut here -- nifty_library.cc ---------- ..... Junk taken out. // declare global objects to resolve external references foo aFoo ("aFoo by library startup"); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This causes aFoo to be constructed and so the foo::foo constructor is called. This is the cause of the second construction by library startup. ..... Junk taken out. > >// counter implementation >nifty_counter::nifty_counter () >{ > if (count++ == 0) { > // initialize global objects > aFoo.foo ("aFoo by nifty_counter"); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Ouch! This makes an explicit call to the contstructor for foo. You should never explicity call a constructor. It is the compiler's job to call constructors. This will certainly cause trouble for you. > } >} > You should never ever call a constructor or destructor yourself. The compiler will do these things for you... Let me recommend that you declare the variable "aFoo" as follows: foo *aFoo; <--- as a pointer to a foo. Now in nifty_counter::nifty_counter() you can create a foo as follows: if (count++ == 0) { aFoo = new foo("aFoo by nifty_counter"); // will call foo::foo for you. } Then in nifty_counter::~nifty_counter() you can destroy the foo as follows: if (--count == 0) { delete aFoo; // will call foo:~foo for you. } Hope this helps. -- +-Robert C. Martin-----+:RRR:::CCC:M:::::M:| Nobody is responsible for | | rmartin@clear.com |:R::R:C::::M:M:M:M:| my words but me. I want | | uunet!clrcom!rmartin |:RRR::C::::M::M::M:| all the credit, and all | +----------------------+:R::R::CCC:M:::::M:| the blame. So there. |
engeln@danetis.UUCP (Werner Engeln) (12/06/90)
rmartin@clear.com (Bob Martin) writes: >You should never ever call a constructor or destructor yourself. The >compiler will do these things for you... >Let me recommend that you declare the variable "aFoo" as follows: > foo *aFoo; <--- as a pointer to a foo. >..... Junk taken out. >Hope this helps. This is no general solution. sometimes I have no pointers but REAL objects (like cin & cout in the AT&T istream & ostream library) >In article <3306@danetis.UUCP> you write: >>To ensure that global objects of a library is initialized befor its first >>use, I implemented a counter to maintain the number of translation units >>using it (see "the annotated C++ reference manual section 3.4, Ellis & >>Stroustrup).[example below] I only have this reference and don't know their mystic tricks to initialize cin and cout by use of a nifty_counter. Is Stroustrup telling lies, or is there any hidden C++ feature ?? -- Werner Engeln Phone: +49-711/736051 FAX: +49-711/736054 Danet-IS GmbH UUCP: engeln@danetis.uucp Waldburgstrasse 17 - 19 BITNET: engeln%danetis.uucp@unido.bitnet D-7000 Stuttgart 80 X.400: C=DE;A=DBP;P=DANET;O=IS;S=Engeln