Topic: calling virtual functions from constuctors


Author: astor@alkymi.unit.no (Alexander S A Kjeldaas)
Date: 13 Jan 1994 13:05:42 GMT
Raw View
class A
{
  public:
    A() {F1();};
    void test() {F1();};
    virtual void F1() {}; // This function is called in the first statement
};

class B : public A
{
  public:
    B() : A() {};
    virtual void F1() {}; // This function is called in the second statement.
};

int main()
{
  B b;
  b.test();
}

I have problems with this piece of code (using Borland 3.1). In the first
statement, A's constructor will call A's virtual F1 function even if b
is of type B. Are there any special rules for calling virtual functions
from the constructor? I thought the compiler might set up the pointers
to the virtual functions too late to catch the function call..or am I on
the wrong track... By the way, the second statement works.

Alex




Author: mm@resumix.portal.com (Martin Malich)
Date: 13 Jan 1994 13:45:29 GMT
Raw View
In article id8@ugle.unit.no,  astor@alkymi.unit.no (Alexander S A Kjeldaas) writes:
>
>class A
>{
>  public:
>    A() {F1();};
>    void test() {F1();};
>    virtual void F1() {}; // This function is called in the first statement
>};
>
>class B : public A
>{
>  public:
>    B() : A() {};
>    virtual void F1() {}; // This function is called in the second statement.
>};
>
>int main()
>{
>  B b;
>  b.test();
>}
>
>I have problems with this piece of code (using Borland 3.1). In the first
>statement, A's constructor will call A's virtual F1 function even if b
>is of type B. Are there any special rules for calling virtual functions
>from the constructor? I thought the compiler might set up the pointers
>to the virtual functions too late to catch the function call..or am I on
>the wrong track... By the way, the second statement works.
>
>Alex


Calling virtual functions from a constructor is a bit dangerous and gets
even more worse when you try to call a pure virtual function:

Look at page 561 of Stroustrup's "The C++ Programming language" second edition:

"Member functions can be called from a constructor of an abstract class;
the effect of calling a pure virtual function directly or indirectly for
the object being created from such a constructor is undefined."


Martin



---
*****************************************************************************
   Martin Malich
   mm@mi.uni-koeln.de
   Mathematisches Institut
   University of Cologne
   Weyertal 86-90
   D-50931 Koeln
   Germany
*****************************************************************************







Author: philr@pcproj.datastream.co.uk (Phil Reynolds)
Date: 13 Jan 1994 14:18:30 -0000
Raw View
Alexander S A Kjeldaas (astor@alkymi.unit.no) wrote:

> class A
> {
>   public:
>     A() {F1();};
>     void test() {F1();};
>     virtual void F1() {}; // This function is called in the first statement
> };

> class B : public A
> {
>   public:
>     B() : A() {};
>     virtual void F1() {}; // This function is called in the second statement.
> };

> int main()
> {
>   B b;
>   b.test();
> }

> I have problems with this piece of code (using Borland 3.1). In the first
> statement, A's constructor will call A's virtual F1 function even if b
> is of type B. Are there any special rules for calling virtual functions
> from the constructor? I thought the compiler might set up the pointers
> to the virtual functions too late to catch the function call..or am I on
> the wrong track... By the way, the second statement works.

The compiler is dead right. When the A part of b is being constructed, the
object is still an A so As virtual function will be called. Once As
constructor has been compleeted, the object becomes a B and Bs virtual
function will be called. If this wasn't the case Bs virtual function
would be called for an uninitialised object.

I hope I havn't over simplified that too much.
--
+-------------------------------+-------------------------+
| Phil Reynolds                 | I just work here.       |
| philr@pcproj.datastream.co.uk | I dont speak for them.  |
| PC-Projects                   | If our views coincide,  |
| Datastream International      | then I must be wrong!   |
+-------------------------------+-------------------------+






Author: bruce@mdavcr.mda.ca (Bruce Thompson)
Date: 13 Jan 94 23:43:01 GMT
Raw View
Martin Malich (mm@resumix.portal.com) wrote:
: In article id8@ugle.unit.no,  astor@alkymi.unit.no (Alexander S A Kjeldaas) writes:
: >
: >class A
: >{
: >  public:
: >    A() {F1();};
: >    void test() {F1();};
: >    virtual void F1() {}; // This function is called in the first statement
: >};
: >
: >class B : public A
: >{
: >  public:
: >    B() : A() {};
: >    virtual void F1() {}; // This function is called in the second statement.
: >};
: >
: >int main()
: >{
: >  B b;
: >  b.test();
: >}
: >
: >I have problems with this piece of code (using Borland 3.1). In the first
: >statement, A's constructor will call A's virtual F1 function even if b
: >is of type B. Are there any special rules for calling virtual functions
: >from the constructor? I thought the compiler might set up the pointers
: >to the virtual functions too late to catch the function call..or am I on
: >the wrong track... By the way, the second statement works.
: >
: >Alex


: Calling virtual functions from a constructor is a bit dangerous and gets
: even more worse when you try to call a pure virtual function:

: Look at page 561 of Stroustrup's "The C++ Programming language" second edition:

: "Member functions can be called from a constructor of an abstract class;
: the effect of calling a pure virtual function directly or indirectly for
: the object being created from such a constructor is undefined."


: Martin



: ---
: *****************************************************************************
:    Martin Malich
:    mm@mi.uni-koeln.de
:    Mathematisches Institut
:    University of Cologne
:    Weyertal 86-90
:    D-50931 Koeln
:    Germany
: *****************************************************************************

However the behavior Alex describes is perfectly correct, and the
behavior _when_not_calling_a_pure_virtual_ is clearly defined. On page
582, section r.12.7 of the same book is stated: "The function called
will be the one defined in the constructor's (or destructor's) own
class or its bases, but _not_ any function overriding it in a derived
class."

The reasoning behind this is due to the order ofconstructor and
destructor calling. Constructos are called in superclass-first order.
This implies that when the constructor for the 'A' part of that object
is called, the 'B' constructor has not been, and therefore the 'B'
does not exist. Only the 'A'. Likewise for destructors. Destructors
are called in subclass-first order which means that by the time 'A's
destructor is called, the 'B' part has already been destroyed, and
therefore the 'B' function should not be called.

 Cheers,
 Bruce.
--
Bruce Thompson, B.Sc.  | "A great many people think they are
Software Engineer  |  thinking when they are merely
MacDonald Dettwiler,  |  rearranging their prejudices."
13800 Commerce Parkway,  | -- William James
Richmond, BC   |
(604) 278-3411   | Usual disclaimers apply
NAPRA #473   |