Why is a virtual call from ctor illegal?

P

Paul Bilnoski

Can someone explain why a call to a virtual function within a
constructor is illegal?
The class can't be instantiated because functions are abstract, so
whatever extends it implements them which means they should be
implemented when the constructor for the base is called.
Is it because the base gets constructed before the rest of the object
and the vftable doesn't exist?
I think something like this works in Java.

class AbstractBase
{
public:
AbstractBase();
virtual ~AbstractBase() { }

virtual void disable() = 0;
virtual void enable() = 0;
virtual bool enabled() = 0;
};

AbstractBase::AbstractBase()
{
disable();
}

--Paul
 
P

Pete Becker

Paul said:
Can someone explain why a call to a virtual function within a
constructor is illegal?

It's not.
The class can't be instantiated because functions are abstract, so
whatever extends it implements them which means they should be
implemented when the constructor for the base is called.
Is it because the base gets constructed before the rest of the object
and the vftable doesn't exist?
I think something like this works in Java.

Yes, Java allows constructors to call virtual functions on the derived
class, which has not been constructed at the time that the function is
called. I suppose there's a sense in which you could say that it
"works", but it can easily lead to surprises.
class AbstractBase
{
public:
AbstractBase();
virtual ~AbstractBase() { }

virtual void disable() = 0;
virtual void enable() = 0;
virtual bool enabled() = 0;
};

AbstractBase::AbstractBase()
{
disable();
}

If you provide a definition for AbstractBase::disable it will be called.
 
P

Paul Bilnoski

Pete said:
It's not.

My G++ and MSVC both gave errors for it. It's looking for a definition
that shouldn't exist because it's abstract.
Yes, Java allows constructors to call virtual functions on the derived
class, which has not been constructed at the time that the function is
called. I suppose there's a sense in which you could say that it
"works", but it can easily lead to surprises.


If you provide a definition for AbstractBase::disable it will be called.

I want the extended classes to provide the definition for it. I could
put an empty body here, but then extensions have to know to override
because it's no longer pure virtual.
 
?

=?ISO-8859-15?Q?Juli=E1n?= Albo

Paul said:
Can someone explain why a call to a virtual function within a
constructor is illegal?

Because the virtual function call depends on the type of object, and the
derived object is not yet constructed. In the example of your message, the
function invoked does not exist (conceptually, it can be a function that
aborts with a message such "pure virtual function invoked", for example).
 
P

Pete Becker

Paul said:
My G++ and MSVC both gave errors for it. It's looking for a definition
that shouldn't exist because it's abstract.

It doesn't exist because you didn't write it. In general you don't have
to provide a definition for a pure virtual function, but if you call it,
of course you have to define it.
I want the extended classes to provide the definition for it. I could
put an empty body here, but then extensions have to know to override
because it's no longer pure virtual.

If it's marked with "=0" it's pure virtual. Doesn't matter whether you
provide a definition.
 
R

Ron Natalie

Pete said:
If it's marked with "=0" it's pure virtual. Doesn't matter whether you
provide a definition.

It's undefined behavior to make a virtual call to a pure virtual
function during constructor (doesn't matter if it's defined or not).
 
P

Paul Bilnoski

Pete said:
It doesn't exist because you didn't write it. In general you don't have
to provide a definition for a pure virtual function, but if you call it,
of course you have to define it.

Why can't the compiler realize that there will be a definition for it at
runtime in a class that doesn't exist yet?
I just think it should compile the abstract base and just link to the
appropriate implementation of the virtual function, not the one defined
locally.
 
P

Pete Becker

Ron said:
It's undefined behavior to make a virtual call to a pure virtual
function during constructor (doesn't matter if it's defined or not).

Good point. Still, it doesn't affect what I just said. <g>
 
P

Pete Becker

Paul said:
Why can't the compiler realize that there will be a definition for it at
runtime in a class that doesn't exist yet?
I just think it should compile the abstract base and just link to the
appropriate implementation of the virtual function, not the one defined
locally.

When you call a function from a constructor or a destructor the compiler
does not dispatch virtually. The derived portion of the class has not
been constructed, so calling functions that belong to it is risky.
 
A

Alf P. Steinbach

* Paul Bilnoski:
My G++ and MSVC both gave errors for it. It's looking for a definition
that shouldn't exist because it's abstract.

You're talking about a pure virtual function.

For a direct call the compiler knows there's no implementation when the call
is executed, so it can detect this (I'm not sure if it's required to).

For an indirect call via some other member function, it can in general not
detect the error -- even in principle.

I want the extended classes to provide the definition for it. I could
put an empty body here, but then extensions have to know to override
because it's no longer pure virtual.

For a newbie this typically indicates a design error.

However, technically it is sometimes needed.

So, the technical how-to is a FAQ:
(I'm not sure what Google has done, but the C++ FAQ main site is no longer
in the first page of results, and for a popular C++ GUI library its main web
page isn't any longer in the results at all: first Google screw up their
usenet interface, and now, it's evidently the web search engine)
<url:
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.3>
<url:
http://www.parashift.com/c++-faq-lite/strange-inheritance.html#faq-23.4>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,161
Messages
2,570,892
Members
47,431
Latest member
ElyseG3173

Latest Threads

Top