Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can you call a pure virtual function from *within* the abstract class?

0 views
Skip to first unread message

Darin Boesch

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
I'm trying to do something, but I'm not sure if it's even possible. Here's
what I have:

class CBase
{
public:
CBase() { Test(); } // Test() gives an unresolved external
virtual ~CBase() { }
protected:
virtual void Test() = 0;
};

When I try this (using a derived class that declares/defines Test(), of
course), my compiler gives me an Unresolved External. That sort of makes
sense to me because it can't find my void CDerived::Test() definition.
However, it doesn't seem right that I should have to #include all of the
files that might implement my base class within the base class header
itself.

It seems to me that what I'm trying to do would come in extremely handy, so
I'm wondering if someone has done this. Am I crazy for thinking this might
work?

Thanks.


[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]
[ about comp.lang.c++.moderated. First time posters: do this! ]


Ian Collins

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
Darin Boesch wrote:

> I'm trying to do something, but I'm not sure if it's even possible. Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };
>
> When I try this (using a derived class that declares/defines Test(), of
> course), my compiler gives me an Unresolved External. That sort of makes
> sense to me because it can't find my void CDerived::Test() definition.
> However, it doesn't seem right that I should have to #include all of the
> files that might implement my base class within the base class header
> itself.
>
> It seems to me that what I'm trying to do would come in extremely handy, so
> I'm wondering if someone has done this. Am I crazy for thinking this might
> work?
>

The constructor for CBase is called before that of the derived class, so there

will be no vtable built. So you can not call a virtual member from a derived
class
from a base class constructor. If Test was not pure virtual, you would see it

called no matter what you added to any derived class.

Ian


Jens Kilian

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
"Darin Boesch" <dbo...@carolina.rr.com> writes:

> I'm trying to do something, but I'm not sure if it's even possible. Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external

Calling a virtual function inside a constructor will NOT call the version
defined in the derived class.

> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };

Note that calling Test() anywhere else within CBase is OK; the constructor is
special in this respect.

HTH,
Jens.
--
mailto:j...@acm.org phone:+49-7031-464-7698 (HP TELNET 778-7698)
http://www.bawue.de/~jjk/ fax:+49-7031-464-7351
PGP: 06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]

Ivan Strougatski

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to

Darin Boesch wrote:
>
> I'm trying to do something, but I'm not sure if it's even possible. Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external

> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };

Duch, you can't do it from constructor and destructor, but you can
do it from normal functions. The reason is that virtual are constructed
bit by bit, so when CBase is executed, it thinks that it is of type
CBase and not it child.

> When I try this (using a derived class that declares/defines Test(), of
> course), my compiler gives me an Unresolved External. That sort of makes
> sense to me because it can't find my void CDerived::Test() definition.
> However, it doesn't seem right that I should have to #include all of the
> files that might implement my base class within the base class header
> itself.
>
> It seems to me that what I'm trying to do would come in extremely handy, so
> I'm wondering if someone has done this. Am I crazy for thinking this might
> work?

--
That Price, who may doe nothing but what's just,
Rules but by leave, and takes his Couwne on trust.

Robert Herrick.

Ian Collins

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
Darin Boesch wrote:

> I'm trying to do something, but I'm not sure if it's even possible. Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };
>

> When I try this (using a derived class that declares/defines Test(), of
> course), my compiler gives me an Unresolved External. That sort of makes
> sense to me because it can't find my void CDerived::Test() definition.
> However, it doesn't seem right that I should have to #include all of the
> files that might implement my base class within the base class header
> itself.
>
> It seems to me that what I'm trying to do would come in extremely handy, so
> I'm wondering if someone has done this. Am I crazy for thinking this might
> work?

The constructor for CBase is called before that of the derived class, so there

will be no vtable built. So you can not call a virtual member from a derived
class
from a base class constructor. If Test was not pure virtual, you would see it

called no matter what you added to any derived class.

Ian


david...@ft.com

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
Sorry Darin, it's not possible. You can't call virtual functions from
within the constructor and have them work as expected. The function
will be called as if non-virtual. In the case of pure virtual
functions, this will usually just crash the program.

The reason for this is that when you construct a derived object, the
base class part gets constructed before the derived part. If a virtual
function is called, there is no derived part yet available, so the
virtual mechanism has nothing to work with.

It may surprise you to know that you can actually provide a base class
implementation even for pure virtual functions, and it can be called
from a constructor, though not polymorphically. Usually such
implementations will only be called explicitly from a derived class, to
provide some common functionality:

void Derived::func()
{
Base::PureVirtualFunc(); // Useful common code
... // do some additional bits
}

Hope this helps,

Dave

In article <liIi4.23707$os2.1...@typhoon.southeast.rr.com>,


"Darin Boesch" <dbo...@carolina.rr.com> wrote:
> I'm trying to do something, but I'm not sure if it's even possible.
Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };
>
> When I try this (using a derived class that declares/defines Test(),
of
> course), my compiler gives me an Unresolved External. That sort of
makes
> sense to me because it can't find my void CDerived::Test() definition.
> However, it doesn't seem right that I should have to #include all of
the
> files that might implement my base class within the base class header
> itself.
>
> It seems to me that what I'm trying to do would come in extremely
handy, so
> I'm wondering if someone has done this. Am I crazy for thinking this
might
> work?

Sent via Deja.com http://www.deja.com/
Before you buy.

Dave Harris

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
dbo...@carolina.rr.com (Darin Boesch) wrote:
> Can you call a pure virtual function from *within* the abstract class?

>From within the class, yes, but in C++ it doesn't make sense to do so from
within the constructor or destructor. During those routines, the derived
part of the object does not yet exist. The dynamic type of *this will be
the same as its static type. To put it another way, the vtbl of the
derived class hasn't yet been installed.

To pick up on other recent threads... this is one reason why "inline
virtuals" are useful, and why we might want a pure virtual to have an
implementation. The compiler has probably emitted a direct call to the
function, ie without going through the vtbl at all or doing any of that
polymorphism nonsense, and this reference is what is causing the linker to
fail.


> However, it doesn't seem right that I should have to #include all of the
> files that might implement my base class within the base class header
> itself.

You don't; it won't help. You could make the linker happy by providing a
default implementation of the pure virtual (which is a matter of linking
rather than #including), but that won't achieve what (I think) you want
here.

Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
bran...@cix.co.uk | And close your eyes with holy dread,
| For he on honey dew hath fed
http://www.bhresearch.co.uk/ | And drunk the milk of Paradise."

Daniel T.

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
In article <liIi4.23707$os2.1...@typhoon.southeast.rr.com>, "Darin
Boesch" <dbo...@carolina.rr.com> wrote:

>I'm trying to do something, but I'm not sure if it's even possible. Here's
>what I have:
>
>class CBase
>{
>public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
>protected:
> virtual void Test() = 0;
>};
>
>When I try this (using a derived class that declares/defines Test(), of
>course), my compiler gives me an Unresolved External. That sort of makes
>sense to me because it can't find my void CDerived::Test() definition.

>However, it doesn't seem right that I should have to #include all of the
>files that might implement my base class within the base class header
>itself.
>

>It seems to me that what I'm trying to do would come in extremely handy, so
>I'm wondering if someone has done this. Am I crazy for thinking this might
>work?

It doesn't work. At the time that Test is being called in the constructor,
your Derived object doesn't exists yet so the compiler doesn't know where
to go for the code of Test.

You could do one of two things...

a) implement test for the base class ( note you can still make it pure
virtual thereby forcing subclasses to override it. )

b) Use the virtual constructor idiom from the FAQ.
http://www.cerfnet.com/~mpcline/c++-faq-lite/virtual-functions.html#[20.5]

Thomas P. Diffenbach

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
dbo...@carolina.rr.com (Darin Boesch) wrote in comp.lang.c++:

>I'm trying to do something, but I'm not sure if it's even
>possible. Here's what I have:
>
>class CBase
>{
>public:
> CBase() { Test(); } // Test() gives an unresolved
> external virtual ~CBase() { }
>protected:
> virtual void Test() = 0;
>};
>
>When I try this (using a derived class that declares/defines
>Test(), of course), my compiler gives me an Unresolved
>External. That sort of makes sense to me because it can't
>find my void CDerived::Test() definition. However, it doesn't
>seem right that I should have to #include all of the files
>that might implement my base class within the base class
>header itself.
>
>It seems to me that what I'm trying to do would come in
>extremely handy, so I'm wondering if someone has done this.
>Am I crazy for thinking this might work?
>

>Thanks.
>
bjects are constructed Base class first. The type of the object
is the type of the currently executing constructor.

Even if the object being constructed is of type Derived, at the
point during construction when (in your example) the CBase
constructor is executing, the type of the object is CBase.

Since the type is (at that point) CBase, virtual function look-
up will not find the derived class's overriding function.
Instead, CBase's (or some base class of CBase, were there one)
function Test() will be called. As you have not defined
CBase::Test(), the compiler properly gives you an error.

For this reason, calling functions in constructors is usually to
be avoided. You COULD define Test() in class CBase(), but since
it still won't call the derived class's Test(), this won't buy
you much.

You could instead call Test() in the derived class constructor,
but you'll run into the same problem if you then derive another
class from that class.

In general, construct the object first, then use it after it is
fully constructed.

A (rather complex) technique to get around this problem is
explored in Coplien's article "Curiously Recurring Template
Patterns" (In Lippmann, _C++ Gems_, p. 135) Essentially, a C++
template class is written that generates a most-derived class
automatically, and the constructor in the most-derived class
calls the initialization fucntions. One parameter to the
template class is the base class from which the template class
is derived:

template< class Base >
class mostDerived : public Base {
public:
MostDerived() { init() ; Test() ; etc() ; }
} ;


Of course, were you to derive from this template, and override
Test() in the derived class, you'd once again have the same
problem.

Another way to get around the problem would be to use another
class to contain the derived object. In that class's
constructor, the derived object would be fully constructed. Of
course, how do you determine what type of derived object is in
the containing class? In you know at compile time, you might use
a template:

template< class T >
class Wrapper {
T contained ;
public:
Wrapper() {
contained.Test() ;
}
} ;

Of course, a Wrapper< Derived1 > is in no way related to a
Wrapper< Derived2 >, so you couldn't use pointers to Wrappers of
holding different contained types, even if the different
contained types are themsleves related.

You might decide to give all Wrappers a common base class:

class CommonBase {
... // common interface
} ;

template< class Contained >
class Wrapper : public CommonBase
... // as above


Or you might decide that class Wrapper hold a reference to a
CBase, pass in an already constructed CBase-Derived, and have
Wrapper call the passed in object's Test():

class Wrapper {
CBase& testable ;
public:
Wrapper( CBase& cb ) : testable( cb ) { testbale.Test() ; }
} ;

Alternately, you might pass in a pointer to a CBase, and have
the Wrapper construct a (default) CBase if teh pointer is null.

Or you can just construct the derived object first, and then
call Test() on it.

--Thomas

Niklas Mellin

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
In article <liIi4.23707$os2.1...@typhoon.southeast.rr.com>,
"Darin Boesch" <dbo...@carolina.rr.com> wrote:
> I'm trying to do something, but I'm not sure if it's even
> possible. Here's what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };

See section 20.5 of the C++ FAQ found at:
http://www.cerfnet.com/~mpcline/On-Line-C++-FAQs/

/Niklas Mellin


Sent via Deja.com http://www.deja.com/
Before you buy.

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Larry Evans

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
Darin Boesch wrote:
>
> I'm trying to do something, but I'm not sure if it's even possible. Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };
>
You can't call a virtual from within the CTOR because, at that time, the
virtual
table is not complete. However, you can call it in a member function.
However, you
can actually implement a pure virtual. In that case, I don't know what
would happen
with your call to Test() in CBase::CBase().

Robert Klemme

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to

hi!

Darin Boesch schrieb:


>
> I'm trying to do something, but I'm not sure if it's even possible. Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };
>

> When I try this (using a derived class that declares/defines Test(), of
> course), my compiler gives me an Unresolved External. That sort of makes
> sense to me because it can't find my void CDerived::Test() definition.

yes, because the call sits in a CONSTRUCTOR.

> However, it doesn't seem right that I should have to #include all of the
> files that might implement my base class within the base class header
> itself.

this does not solve your problem either.

> It seems to me that what I'm trying to do would come in extremely handy, so
> I'm wondering if someone has done this. Am I crazy for thinking this might
> work?

the answer to your question in the subject is "yes, if it is not a
constructor or destructor".

but the answer to what you showed in the code is "no".

explanation: it is perfectly ok to call a pure virtual method in a base
class method unless it is a constructor or the destructor. because
those do work on an object that is at this point in time just a base
class object. and here the method reference is undefined. you could
add a public method

void doit() { Test(); }

and this will work, if you call this method after construction.

regards

robert


--
Robert Klemme
Internet Consultant/Berater
-------------------------------------------------------------
myview technologies / Global Cooperation System GmbH & Co. KG
Riemekestraße 160 ~ D-33106 Paderborn ~ Germany
E-Mail: mailto:kle...@myview-technologies.com
Telefon: +49/5251/69090-321 ~ Fax: +49/5251/69090-399
-------------------------------------------------------------

Gerhard Menzl

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
Darin Boesch wrote:

> I'm trying to do something, but I'm not sure if it's even possible.
> Here's what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };
>
> When I try this (using a derived class that declares/defines Test(), of
> course), my compiler gives me an Unresolved External. That sort of makes
> sense to me because it can't find my void CDerived::Test() definition.
> However, it doesn't seem right that I should have to #include all of the
> files that might implement my base class within the base class header
> itself.
>
> It seems to me that what I'm trying to do would come in extremely handy,
> so I'm wondering if someone has done this. Am I crazy for thinking this
> might work?

Not crazy, merely subject to a common misunderstanding. :-)

While it is legal to call virtual functions from within constructors and
destructors of base classes, they won't work as you seem to expect. At the
time CBase::CBase() is executed, the CDerived part of the object hasn't
been constructed yet, therefore the version of Test() being called is that
of the class under construction, i.e. CBase. Since CBase::Test() is a pure
virtual function that doesn't have an implementation, your compiler (or,
more likely, your linker) rightly complains that the function doesn't
exist. Similarly, when a base class destructor is being executed the
derived part doesn't exist anymore.

Gerhard Menzl

Mark Solinski

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to

"Darin Boesch" <dbo...@carolina.rr.com> wrote in message
news:liIi4.23707$os2.1...@typhoon.southeast.rr.com...

> I'm trying to do something, but I'm not sure if it's even possible. Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };
>
> When I try this (using a derived class that declares/defines Test(), of
> course), my compiler gives me an Unresolved External. That sort of makes
> sense to me because it can't find my void CDerived::Test() definition.
> However, it doesn't seem right that I should have to #include all of the
> files that might implement my base class within the base class header
> itself.

The main problem is that you are calling Test() from inside a constructor.
When you
instantiate a CDerived object, the CBase constructor is called before the
CDerived constructor and you do not have a complete CDerived object. If you
had called Test inside a method such as CBase::Init() and then called
CDerivedObject.Init() after the CDerivedObject was constructed, you would
have no problem and it would work the way you expected.

> It seems to me that what I'm trying to do would come in extremely handy,
so
> I'm wondering if someone has done this. Am I crazy for thinking this might
> work?
>

> Thanks.

Daniel M. Pfeffer

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
The problem with your code is a subtle one. Classes are constructed from the
base class(es) to the most derived class(es). For example, given the
following hierarchy:

class base {
// details omitted
};

class derived: public base {
// details omitted
};

derived x;

the code first constructs the base object, and only then constructs the part
of the object defined by the 'derived' class, modifying the virtual method
table (VMT) if necessary.

At the time that the constructor of your 'CBase' class is called, the
'CBase' object's VMT is initialised, BUT the values in it are those known to
the 'CBase' class, i.e. pointers to 0! Calling via a null pointer is
undefined. :-/

You may only call the pure virtual Test() method when you know that your
CBase is part of a derived class that has already initialised the VMT. This
is guaranteed from the point at which the derived class' constructor starts
executing to the point at which its destructor returns.

Example:

class CBase {
public:
CBase()
{
Test(); // will crash - calls "pure virtual" function
foo(); // will crash
}
virtual ~CBase();

void foo() { Test(); } // result depends on whether the object is
"really" CBase or CDerived.

protected:
virtual void Test() = 0;

class CDerived : public CBase {
public:
CDerived()
: CBase() // at this point it is illegal to call Test() (i.e. in
constructor of CBase)
{ // OK to call Test() from in here
Test(); // calls CDerived::Test()
foo(); // will call CDerived::Test()
}

~CDerived()
{ // still OK to call Test()
} // Test() may not be called once this executes
(i.e. in the destructor of CBase)

protected:
virtual void Test() { /* ... */ }
};

I hope this helps.

Daniel Pfeffer


"Darin Boesch" <dbo...@carolina.rr.com> wrote in message news:liIi4.23707$o
s2.1...@typhoon.southeast.rr.com...
> I'm trying to do something, but I'm not sure if it's even possible. Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };
>
> When I try this (using a derived class that declares/defines Test(), of
> course), my compiler gives me an Unresolved External. That sort of makes
> sense to me because it can't find my void CDerived::Test() definition.
> However, it doesn't seem right that I should have to #include all of the
> files that might implement my base class within the base class header
> itself.
>

Gaurav Sareen

unread,
Jan 24, 2000, 3:00:00 AM1/24/00
to
> CBase() { Test(); } // Test() gives an unresolved external

Here always CBase::Test() is called, the reason being that the derived class
is not even there yet for its methods to be called.

> However, it doesn't seem right that I should have to #include all of the
> files that might implement my base class within the base class header
> itself.

This has nothing to do with "#include". The external references are resolved
while linking. Its while linking that the linker finds no definition for
CBase::Test() and complains, no #include would avoid that.

>
> It seems to me that what I'm trying to do would come in extremely handy,
so
> I'm wondering if someone has done this. Am I crazy for thinking this might
> work?

I think what you need is a "virtual constructor" Look for the same in the
faq

Thomas A. Horsley

unread,
Jan 25, 2000, 3:00:00 AM1/25/00
to
OK, there are now 10,000 replies to the original poster's question all
of them explaining why you can't call virtuals in constructors.

I have another question: Why doesn't C++ have post-constructors? (And
pre-destructors, for that matter?) This would solve the problems people
always have with this very issue, and would be the single most useful
feature I can think of for C++.
--
>>==>> The *Best* political site <URL:http://www.vote-smart.org/> >>==+
email: Tom.H...@worldnet.att.net icbm: Delray Beach, FL |
<URL:http://home.att.net/~Tom.Horsley> Free Software and Politics <<==+

Steve Clamage

unread,
Jan 25, 2000, 3:00:00 AM1/25/00
to
Darin Boesch wrote:
>
> I'm trying to do something, but I'm not sure if it's even possible. Here's
> what I have:
>
> class CBase
> {
> public:
> CBase() { Test(); } // Test() gives an unresolved external
> virtual ~CBase() { }
> protected:
> virtual void Test() = 0;
> };
>
> When I try this (using a derived class that declares/defines Test(), of
> course), my compiler gives me an Unresolved External.

The program ordinarily should link successfully, but fail at run
time, probably with an abort and core dump.

When you call a member function from a constructor, you get the
function declared in the constructor's own class, or inherited
from a base class. A virtual function call in a constructor cannot
resolve to a function from any derived class. (Same for destructors.)

The reason is that during construction, the derived parts have not
yet been constructed, so running a derived function is unlikely
to be correct. If it is nevertheless what you want to do, you
have to solve the problem some other way. (You should probably
rethink the design; running a derived function on a base object
violates the C++ object model. If the function you want to call
does not depend on the derived object, why is it a member of
the derived class and not of the base class?)

But a function declared pure virtual cannot validly be called via
the virtual function call mechanism. When in a member function
you write "Test()", it is equivalent to "this->Test()", which
in principle invokes the virtual call mechanism. The result of
invoking a pure virtual function via the virtual function call
mechanism, which is what your code does, is undefined. Typical
implementations report a run-time error and abort, but "undefined"
means that you cannot depend on any particular result.

The only way you can legitimately call a pure virtual function is by
qualifying the name explicitly:
CBase::Test();
In that case, you must of course provide a definition for the
function. If you don't, you will most likely get a link error.

Seemingly an exception to the pure virtual function rule is a pure
virtual destructor. If for some reason you declare a destructor
to be pure virtual (which seems to me to have theoretical but not
practical value), you must provide a defintion for the function.
It will always be called automatically in the same way as a non-pure
virtual destructor.

--
Steve Clamage, stephen...@sun.com

Michiel Salters

unread,
Jan 27, 2000, 3:00:00 AM1/27/00
to
"Thomas A. Horsley" wrote:

> OK, there are now 10,000 replies to the original poster's question all
> of them explaining why you can't call virtuals in constructors.

> I have another question: Why doesn't C++ have post-constructors? (And
> pre-destructors, for that matter?) This would solve the problems people
> always have with this very issue, and would be the single most useful
> feature I can think of for C++.

As Valentin Bonnard already pointed out, this is the greatest number of
missing features from C++:

post-constructors, post-post-constructors, post-post-post-constructors, ...

Currently constructors are called in order of derivation, starting with
Base and going to Derived, which makes sense because Base shouldn't
assume things about Derived, but Derived knows everything about Base.
If you need to go the other direction, the Derived constructor is
allowed to call any (virtual) function in Base.

Let me illustrate this:

t Base::Base()
Middle::Middle()
| Derived::Derived()
v Middle::PostConstructor()
Base::Postconstructor()

Therefore, this feature isn't needed in C++.

Michiel Salters

Jim Hyslop

unread,
Jan 27, 2000, 3:00:00 AM1/27/00
to
In article <sf66wjr...@bstde026.bbn.hp.com>,
Jens Kilian <Jens_...@agilent.com> wrote:
[snip]

> Calling a virtual function inside a constructor will NOT call the
> version
> defined in the derived class.
Don't forget the destructor - by the time the body of your dtor
executes, any trace that it used to be a derived class has been wiped
out, so (again) derived overriders will not be called.

--
Jim
I ignore all email from recruitment agencies.
Please do not send me email with questions - post
here.


Sent via Deja.com http://www.deja.com/
Before you buy.

[ Send an empty e-mail to c++-...@netlab.cs.rpi.edu for info ]

Francis Glassborow

unread,
Jan 27, 2000, 3:00:00 AM1/27/00
to
In article <uiu0jn...@worldnet.att.net>, Thomas A. Horsley
<Tom.H...@worldnet.att.net> writes

>OK, there are now 10,000 replies to the original poster's question all
>of them explaining why you can't call virtuals in constructors.
>
>I have another question: Why doesn't C++ have post-constructors? (And
>pre-destructors, for that matter?) This would solve the problems people
>always have with this very issue, and would be the single most useful
>feature I can think of for C++.

You are obviously not one of those that think the Standard's committees
added too much to the language:)


Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation

Ron Natalie

unread,
Jan 27, 2000, 3:00:00 AM1/27/00
to

> I have another question: Why doesn't C++ have post-constructors? (And
> pre-destructors, for that matter?) This would solve the problems people
> always have with this very issue, and would be the single most useful
> feature I can think of for C++.

Because I guess it fails the conceptual model, and if you really want
to do it you can usually fake it either with encapsulation in another
class or wrapping the construction procedure for dynamic objects. Not
the cleanest I admit, but not impossible.

Gaurav Sareen

unread,
Jan 27, 2000, 3:00:00 AM1/27/00
to
> I have another question: Why doesn't C++ have post-constructors? (And
> pre-destructors, for that matter?) This would solve the problems people
> always have with this very issue, and would be the single most useful
> feature I can think of for C++.


The way to thionk of regular constructors and destructors is to treat them
as pre-constructors and post destructors and have an init() and destroy()
for all non-trivial cases.

But I dont think the language needs to be modified to do this, there is
nothing preventing a discerning user to do that.

Craig Thrall

unread,
Jan 28, 2000, 3:00:00 AM1/28/00
to
> >I have another question: Why doesn't C++ have post-constructors? (And
> >pre-destructors, for that matter?) This would solve the problems people
> >always have with this very issue, and would be the single most useful
> >feature I can think of for C++.

What's preventing you from writing them? I usually call mine init and
terminate, but to each their own.

Craig

James Grant

unread,
Jan 29, 2000, 3:00:00 AM1/29/00
to

Gaurav Sareen <nee...@hotmail.com> wrote in message
news:EJFj4.5427$t_.1...@news.rdc1.nj.home.com...

>
> The way to thionk of regular constructors and destructors is to treat them
> as pre-constructors and post destructors and have an init() and destroy()
> for all non-trivial cases.
>
> But I dont think the language needs to be modified to do this, there is
> nothing preventing a discerning user to do that.
>

What is your reasoning behind this? Why shouldn't the constructor be used
for all initialisation tasks and the destructor be used for all cleanup
tasks? I would say that this would be the choice of the discerning c++
user.

James Grant

Phlip

unread,
Jan 29, 2000, 3:00:00 AM1/29/00
to
James Grant wrote:
>
> Gaurav Sareen wrote:

> > The way to thionk of regular constructors and destructors is to
treat them
> > as pre-constructors and post destructors and have an init() and
destroy()
> > for all non-trivial cases.

The constructor must do the minimum needed to let the destructor
work properly without any intervening method calls. More is
optional.

> > But I dont think the language needs to be modified to do this,
there is
> > nothing preventing a discerning user to do that.

> What is your reasoning behind this? Why shouldn't the constructor
be used
> for all initialisation tasks and the destructor be used for all
cleanup
> tasks? I would say that this would be the choice of the
discerning c++
> user.

Because "all initialization tasks" can include side-effects.

If client A wants to create an object and instantly use it, they
care not that the side effects happen at construction time.

But if a new client, B, wants to create an object, keep it dormant
for a while, and _then_ use it, the side-effects happened at an
inappropriate time. The sad hack to get around this is for client B
to use a pointer to the object, and 'new' an object there to make it
not dormant. This is sad because it uses pointers to only create a
simple technique that should have taken care of itself - activating
an object.

In general, don't write code containing functionality that predicts
the future. But _do_ make educated guesses about _structure_ that
predict the future. Guess that your object will be used by clients
like B, and give it a separate initialization method. BTW the
'Terminate()' method should expect to be called without anything to
terminate, and the destructor should call it.

--
Phlip
======= http://users.deltanet.com/~tegan/home.html =======

0 new messages