home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!know!cass.ma02.bull.com!mips2!news.bbn.com!usc!zaphod.mps.ohio-state.edu!wupost!darwin.sura.net!convex!news.utdallas.edu!corpgate!bnrgate!bnr.co.uk!pipex!demon!trmphrst.demon.co.uk!nikki
- From: nikki@trmphrst.demon.co.uk (Nikki Locke)
- Newsgroups: comp.lang.c++
- Subject: Re: Calling pure virtual functions in base class constructor
- Message-ID: <721505557snx@trmphrst.demon.co.uk>
- Date: 11 Nov 92 11:12:37 GMT
- Sender: usenet@gate.demon.co.uk
- Reply-To: nikki@trmphrst.demon.co.uk
- Organization: Trumphurst Ltd.
- Lines: 115
- X-Mailer: cppnews $Revision: 1.20 $
-
- In article <1992Nov10.010626.26528@ucc.su.OZ.AU> maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:
- > In article <720990361snx@trmphrst.demon.co.uk> nikki@trmphrst.demon.co.uk writes:
- > > ... it is quite legal to have a definition of a pure
- > >virtual function, thus ...
- > >
- > >class A
- > > {
- > > // ...
- > > ~A() { purefunc(); }
- > > virtual void purefunc() = 0;
- > > };
- > >
- > >void A::purefunc()
- > >{
- > > cout << "You called a pure virtual function !\n";
- > >}
- > >
- > >This facility might be useful when you want your abstract base class to
- > >provide some kind of default behaviour, but you want to force derived
- > >classes to add additional behaviour (or, at least, hint strongly :-).
- It seems I did not explain this too well. Ask yourself what use is a
- definition of a pure virtual function ? It can only be called statically,
- so why not make a non-virtual function (with a different name) to do the
- job ? The only reason _I_ can think of is to hint to the person deriving
- from the class that some of the common/default things they want to do in
- their derived function are already written for them. It is quite common in
- a virtual function in a derived class to call the base class version as
- well as adding derived class specific behaviour. This is why I used
- the term "default behaviour".
-
- Alternative explanations for the _usefulness_ of definitions of pure
- virtuals welcome.
-
- >
- > Not quite. It does not supply 'default behaviour', but
- > is called in two by a statically, i.e. like
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Sorry, don't understand a word of this !
- > A::purefunc(); // from inside a member
- Yes, this is how you force a call to a pure virtual.
- > a.purefunc(); // from outside the object
- Surely this will NEVER call the pure virtual, because you cannot have an
- object of type A (A is an abstract class).
-
- We were discussing a call in a base class destructor. I thought this would
- always call the pure virtual (because any derived class object has
- already been destructed at that point). However, I have re-read the ARM
- (s10.3 p215), and it gives an example ...
-
- arm> class A {
- arm> virtual void f() = 0;
- arm> A() {
- arm> A::f(); // ok
- I ask, why is the A:: necessary here ? If f was NOT pure, A::f would
- definitely be called, because there is no other f is available during the
- constructor. Is it just to make the compiler writer's life one tiny bit
- easier (i.e. always despatch via the vtable unless A:: is present) ?
- arm> }
- arm> };
- arm>
- arm> void A::f() // defined somewhere
- arm> {
- arm> // ...
- arm> }
-
- The arm also states (s12.7 p295)
- arm> The effect of calling a pure virtual function directly or indirectly
- arm> for the object being constructed from a constructor, except using
- arm> explicit qualification, is undefined.
- So the insistence on the A:: qualification is definitely deliberate. Can
- anyone explain why ? (Bjarne ?)
-
- > >
- > >Actually, it occurrs to me that it should be possible to do this yourself,
- > >without adding to code size (probably) - just declare your virtual
- > >functions ...
- > >
- > >class A
- > > {
- > > // ...
- > > ~A() { purefunc(); }
- > > virtual void purefunc() = 0;
- > > };
- > >
- > >inline void A::purefunc() { assert(0); }
- >
- > No, this cannot work. The body of a pure virtual cannot be
- > called though a pointer or reference, only from a 'value'. Had
- > the pure specifier not been included, the body would have been
- > called virtually during construction of the A base only.
- You CAN (IMHO) call a pure virtual using a pointer or reference, using
- pointer->A::purefunc();
-
- > >Pure virtual functions can only be called explicitly, under circumstances
- > >where the actual type can be deduced at compile time, which are the
- > >conditions allowing inline virtuals to be expanded inline. Then again, I
- > >could be wrong.
- >
- > IMHO you are wrong. It is not a matter of deduction, the programmer
- > must explicitly override the virtual call mechanism. Virtual calls
- > (indirections via the vtble) can be replaced by direct calls only
- > in code outside the object where the compiler can deduce the actual
- > object type, this cannot ever be the case inside a member function
- > as far as I can see (because no member can know what the most derived
- > object is).
- After my re-reading of the ARM, I realise that I am, indeed, wrong.
- Despite the fact that the compiler can easily convert calls to any
- virtual function (pure or otherwise) to a direct call in a constructor or
- destructor, the ARM states that it should NOT do so in the case of pure
- virtuals.
-
- Sorry about the length of this posting, but I really would like to
- understand the reasons for all this :-)
- --
- Nikki Locke,Trumphurst Ltd.(PC and Unix consultancy) nikki@trmphrst.demon.co.uk
- trmphrst.demon.co.uk is NOT affiliated with ANY other sites at demon.co.uk.
-