home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.lang.c++
- Path: sparky!uunet!microsoft!hexnut!jimad
- From: jimad@microsoft.com (Jim Adcock)
- Subject: Re: Overriding the order of constructors?
- Message-ID: <1992Dec15.191248.24996@microsoft.com>
- Date: 15 Dec 92 19:12:48 GMT
- Organization: Microsoft Corporation
- References: <1992Dec13.220943.22047@jarvis.csri.toronto.edu> <robison1.724307343@husc10> <Bz8oGx.B7x@well.sf.ca.us>
- Keywords: constructor ordering
- Lines: 103
-
- In article <Bz8oGx.B7x@well.sf.ca.us> johnrp@well.sf.ca.us (John Panzer) writes:
- |In article <robison1.724307343@husc10> robison1@husc10.harvard.edu (Keith Robison) writes:
- |> I believe you can effectively accomplish this dangerous
- |>goal by calling virtual functions in your constructors:
- |>
- |>
- |>class A {
- |> A() { reroute(); do_A_ctor_stuff(); }
- |> virtual void reroute(); { }
- |>}
- |>
- |>class B : public A {
- |> B() {}
- |> void reroute () { do_B_ctor_stuff(); }
- |>}
- |>
- |>
- |>This will cause B's reroute() to be executed before any
- |>A constructing has occurred.
- |>
- |
- |Are you certain? I believe that A::reroute() will
- |be called if reroute() is called from within A's
- |constructor or destructor. I think this is a
- |common C++ "gotcha" - it's certainly gotten me
- |in the past.
-
- Before A::A() is executed on your object, your object is only
- a bag o' bits. It is only a bag o' bits.
-
- When A::A() begins executing on your object, your object becomes
- an A. It may not be a fully formed A, because fully forming A
- is your job inside A::A().
-
- When B::B() begins executing on your object, your object becomes
- an B. It may not be a fully formed B, because fully forming B
- is your job inside B::B().
-
- ....
-
- When B::~B() begins executing on your object, your object becomes
- an B. It may not be a fully deformed B, because fully deforming B
- is your job inside B::~B().
-
- When A::~A() begins executing on your object, your object becomes
- an A. It may not be a fully deformed A, because fully deforming A
- is your job inside A::~A().
-
- After A::~A() executes on your object, your object is only a
- bag o' bits.
-
- ======
-
- In the case of constructors/destructors of objects with virtual functions,
- compilers typically *actually* implement these "type changes" of your
- object, as it is being formed or deformed by its various constructors
- or destructors, *by dynamically changing your object vtable pointer[s]*.
- If you haven't actually looked at the assembly code generated for some
- simple constructors/destructors and inheritence, its well worth the
- exercise! There be dragons!
-
- [Note that compilers have been known to screw this stuff up.]
-
- Below find a little hack program that may ;-) demonstrate modification
- of the vtable ptrs during construction / destruction on your system:
-
- #include <stdio.h>
-
- class A
- {
- public:
- virtual void print();
- virtual int size();
- A() { printf(" A() "); print(); }
- virtual ~A() { printf("~A() "); print(); }
- };
-
- void A::print()
- {
- for (int i=0; i<size(); ++i)
- printf("%02X ", (unsigned)*(((unsigned char*)this)+i));
- printf("\n");
- }
-
- int A::size() { return sizeof(A); }
-
- class B : public A
- {
- long L;
- public:
- virtual int size();
- B() : L(0x12345678) { printf(" B() "); print(); }
- virtual ~B() { L = 0x55555555; printf("~B() "); print(); }
- };
-
- int B::size() { return sizeof(B); }
-
- main()
- {
- B b;
-
- return 0;
- }
-