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=Engeln
rmartin@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