virtual member function in constructor

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Karsten Hochkirch

    virtual member function in constructor

    Hi,

    I have just encountered a problem when calling a virtual member function
    in a constructor.
    Only the memberfunction of the parent class is called instead of the
    overloaded function.

    I have attached a small example.

    Is that bug or feature. If feature: is there an easy way to get the
    behaviour as I am looking for?

    Thanks

    Karsten



    #include <iostream>
    using namespace std;
    class A {
    public:

    virtual A(){init();}
    virtual ~A(){}
    virtual void init(){
    cout << "class A::init\n";
    }
    void test(){init();}

    };

    class B: public A{
    public:
    B():A(){}
    virtual ~B(){}
    virtual void init(){
    cout << "class B::init\n";
    }
    };

    int main(int,char** ){


    // only class A's init is called
    B b;

    // works as I expected
    b.test();
    return 0;

    }


  • Karsten Hochkirch

    #2
    Re: virtual member function in constructor

    Oops,

    the 'virtual' in front of the constructor was just desparate try I
    forgot to remove before attaching the file...

    Karsten Hochkirch wrote:
    [color=blue]
    > Hi,
    >
    > I have just encountered a problem when calling a virtual member
    > function in a constructor.
    > Only the memberfunction of the parent class is called instead of the
    > overloaded function.
    >
    > I have attached a small example.
    >
    > Is that bug or feature. If feature: is there an easy way to get the
    > behaviour as I am looking for?
    >
    > Thanks
    >
    > Karsten
    >
    >------------------------------------------------------------------------
    >
    >
    >
    >#include <iostream>
    >using namespace std;
    >class A {
    > public:
    >
    > virtual A(){init();}
    > virtual ~A(){}
    > virtual void init(){
    > cout << "class A::init\n";
    > }
    > void test(){init();}
    >
    >};
    >
    >class B: public A{
    > public:
    > B():A(){}
    > virtual ~B(){}
    > virtual void init(){
    > cout << "class B::init\n";
    > }
    >};
    >
    >int main(int,char** ){
    >
    >
    > // only class A's init is called
    > B b;
    >
    > // works as I expected
    > b.test();
    > return 0;
    >
    >}
    >
    >
    >[/color]

    Comment

    • Jonathan Turkanis

      #3
      Re: virtual member function in constructor


      "Karsten Hochkirch" <K.Hochkirch@vb ew.net> wrote in message
      news:bveece$eg2 $1@online.de...[color=blue]
      > Hi,
      >
      > I have just encountered a problem when calling a virtual member[/color]
      function[color=blue]
      > in a constructor.[/color]

      Within a constructor, virtual calls are resolved using the vtable of
      the class in which the constructor is defined, rather than the vtable
      of the fully derived type of the object being constructed. Therefore,
      you must be very careful when calling virtual functions from
      constructors; in particular, the possibility of calling a pure virtual
      function exists.

      Jonathan


      Comment

      • Ron Natalie

        #4
        Re: virtual member function in constructor


        "Karsten Hochkirch" <K.Hochkirch@vb ew.net> wrote in message news:bveece$eg2 $1@online.de...
        [color=blue]
        >
        > Is that bug or feature. If feature: is there an easy way to get the
        > behaviour as I am looking for?[/color]

        That is the way it is supposed to work. For the duration of the execution of the
        the constructor body, the dynamic type of the object is considered to be that of
        the constructor that is running. The primary reason is that the derived class has
        yet to be initialized (the base class constructor is run first), so you don't want to
        be roaming around in the derived code.

        The work around is to place any virtual function based common initialization in
        a base class member function other than the constructor and then call it from
        the derived constructor.

        The same thing happens for destructors (just in the reverse order).

        Comment

        • Le Géant Vert

          #5
          Re: virtual member function in constructor

          Karsten Hochkirch wrote:
          [color=blue]
          > Oops,
          >
          > the 'virtual' in front of the constructor was just desparate try I
          > forgot to remove before attaching the file...
          >
          > Karsten Hochkirch wrote:
          >[color=green]
          >> Hi,
          >>
          >> I have just encountered a problem when calling a virtual member
          >> function in a constructor.
          >> Only the memberfunction of the parent class is called instead of the
          >> overloaded function.
          >>
          >> I have attached a small example.
          >>
          >> Is that bug or feature. If feature: is there an easy way to get the
          >> behaviour as I am looking for?
          >>
          >> Thanks
          >>
          >> Karsten
          >>[/color][/color]
          this is not really a feature, this is the way things are supposed to
          happen... When the constructor's called, the object does not exist yet :
          so the code of your overloaded virtual method is unknown and unreachable
          ; thus, only the one of the parent class can be called.
          (a funny thing you can do once you've understood this, is to use it to
          call code of a pure virtual method)
          the tip I'd told you is to never call any method in a constructor, and
          if needed, to provided an init() that should be called by the programmer
          (not as you're doing in your code sample, where init() is called from
          the ctor)

          Comment

          • Alf P. Steinbach

            #6
            Re: virtual member function in constructor

            On Fri, 30 Jan 2004 15:31:10 -0500, "Ron Natalie" <ron@sensor.com > wrote:
            [color=blue]
            >
            >"Karsten Hochkirch" <K.Hochkirch@vb ew.net> wrote in message news:bveece$eg2 $1@online.de...
            >[color=green]
            >>
            >> Is that bug or feature. If feature: is there an easy way to get the
            >> behaviour as I am looking for?[/color]
            >
            >[/color]
            [Correct explanation of why, snipped.]

            See also the FAQ:
            <url: http://www.parashift.c om/c++-faq-lite/strange-inheritance.htm l#faq-23.3>


            [color=blue]
            >The work around[/color]

            Actually there are many different workarounds.

            The most common workarounds are also in the FAQ (I'm happy to take much credit
            for their inclusion, although credit for the text goes to Marshall Cline):

            <url: http://www.parashift.c om/c++-faq-lite/strange-inheritance.htm l#faq-23.4>


            [color=blue]
            > is to place any virtual function based common initialization in
            >a base class member function other than the constructor and then call it from
            >the derived constructor.[/color]

            This only seems to allow virtuality for one level of class derivation.

            It's not a commonly used workaround.

            I don't recommend it, but perhaps it should be included among the others in
            the FAQ?

            Comment

            • David Harmon

              #7
              Re: virtual member function in constructor

              On Fri, 30 Jan 2004 21:21:34 +0100 in comp.lang.c++, Karsten Hochkirch
              <K.Hochkirch@vb ew.net> was alleged to have written:[color=blue]
              >I have just encountered a problem when calling a virtual member function
              >in a constructor.
              >Only the memberfunction of the parent class is called instead of the
              >overloaded function.[/color]

              This issue is covered in Marshall Cline's C++ FAQ. See the topic
              "[23.3] When my base class's constructor calls a virtual function on its
              this object, why doesn't my derived class's override of that virtual
              function get invoked?" It is always good to check the FAQ before
              posting. You can get the FAQ at:



              Comment

              • Karsten Hochkirch

                #8
                Re: virtual member function in constructor

                Ok, I think I understand by now.


                Thanks to all of you for the anwers!!


                Comment

                Working...