calling pure virtual in abstract class's constructor

Discussion in 'C++' started by vsgdp, Sep 24, 2005.

  1. vsgdp

    vsgdp Guest

    I have an abstract class A:

    class A
    {
    public:
    A(){ f(); }
    virtual void f() = 0;
    };

    class B : public A
    {
    public:
    void f() {...}
    };

    B b;

    However, the compiler does not like me calling f in the constructor of A.
    But this seems like it should be okay since A is pure virtual, f will be
    given in derived classes and exist.
    vsgdp, Sep 24, 2005
    #1
    1. Advertising

  2. vsgdp

    Axter Guest

    vsgdp wrote:
    > I have an abstract class A:
    >
    > class A
    > {
    > public:
    > A(){ f(); }
    > virtual void f() = 0;
    > };
    >
    > class B : public A
    > {
    > public:
    > void f() {...}
    > };
    >
    > B b;
    >
    > However, the compiler does not like me calling f in the constructor of A.
    > But this seems like it should be okay since A is pure virtual, f will be
    > given in derived classes and exist.


    This is not OK, because when you're inside constructor A, B has not
    been constructed yet. So you can't call on something that doesn't
    exist yet.
    Remember, that constructor A, gets constructed before constructor B.
    That means any functions in class B, is not avialable to constructor A.
    Axter, Sep 24, 2005
    #2
    1. Advertising

  3. vsgdp

    Ian Guest

    vsgdp wrote:
    > I have an abstract class A:
    >
    > class A
    > {
    > public:
    > A(){ f(); }
    > virtual void f() = 0;
    > };
    >
    > class B : public A
    > {
    > public:
    > void f() {...}
    > };
    >
    > B b;
    >
    > However, the compiler does not like me calling f in the constructor of A.
    > But this seems like it should be okay since A is pure virtual, f will be
    > given in derived classes and exist.
    >

    During A's constructor, there is no B, thus no f() to call.

    You can't call a virtual method form a base class constructor.

    Ian
    Ian, Sep 24, 2005
    #3
  4. vsgdp

    Peter_Julian Guest

    "vsgdp" <> wrote in message
    news:LiiZe.15986$mH.13288@fed1read07...
    | I have an abstract class A:
    |
    | class A
    | {
    | public:
    | A(){ f(); }
    | virtual void f() = 0;
    | };
    |
    | class B : public A
    | {
    | public:
    | void f() {...}
    | };
    |
    | B b;
    |
    | However, the compiler does not like me calling f in the constructor of
    A.
    | But this seems like it should be okay since A is pure virtual, f will
    be
    | given in derived classes and exist.
    |

    Consider that A's ctor is invoked and completed before B's ctor is
    finally processed to completion. The vtable is available but unpopulated
    during A's construction.

    Recall the sequence of construction / destruction for an instance of B:

    <- B's ctor is actually invoked here, vtable created but unpopulated
    A()
    <- populated vtable (at last)
    B() // B's ctor is processed to completion

    .... <- valid instance of B

    ~B()
    ~A()

    If you call f() in B's ctor, the issue disappears since a populated
    vtable is available for this instance of B.

    #include <iostream>

    class A
    {
    public:
    A(){ std::cout << "A()\n"; }
    virtual ~A(){ std::cout << "~A()\n"; }
    virtual void f() = 0;
    };

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

    int main()
    {
    B b;

    return 0;
    }

    /*
    A()
    B()
    B::f()
    ~B()
    ~A()
    */

    Additionally, in C++ you could even have implemented the pure virtual
    A::f() and called it from B::f().
    Peter_Julian, Sep 24, 2005
    #4
  5. Ian wrote:
    > vsgdp wrote:
    > > I have an abstract class A:
    > >
    > > class A
    > > {
    > > public:
    > > A(){ f(); }
    > > virtual void f() = 0;
    > > };
    > >
    > > class B : public A
    > > {
    > > public:
    > > void f() {...}
    > > };
    > >
    > > B b;
    > >
    > > However, the compiler does not like me calling f in the constructor of A.
    > > But this seems like it should be okay since A is pure virtual, f will be
    > > given in derived classes and exist.
    > >

    > During A's constructor, there is no B, thus no f() to call.
    >
    > You can't call a virtual method form a base class constructor.
    >
    > Ian


    Mayer's descusses it at length - READ IT
    puzzlecracker, Sep 24, 2005
    #5
  6. vsgdp

    vsgdp Guest


    >
    > Mayer's descusses it at length - READ IT
    >


    Do you mean Meyers? And do you know which tip # it is? I have his 3
    effective books.
    vsgdp, Sep 24, 2005
    #6
  7. On Sat, 24 Sep 2005 13:04:52 -0700, "vsgdp" <> wrote:

    >However, the compiler does not like me calling f in the constructor of A.
    >But this seems like it should be okay since A is pure virtual, f will be
    >given in derived classes and exist.


    http://www.parashift.com/c -faq-lite/ctors.html#faq-10.7
    Dave Rahardja, Sep 25, 2005
    #7
  8. vsgdp

    Ron Natalie Guest


    >
    > However, the compiler does not like me calling f in the constructor of A.
    > But this seems like it should be okay since A is pure virtual, f will be
    > given in derived classes and exist.
    >
    >


    The standard specifically says this is undefined behavior (virtual call
    to pure virtual constructor during contruction or destruction).
    Ron Natalie, Sep 25, 2005
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. cppsks
    Replies:
    6
    Views:
    426
    Victor Bazarov
    Nov 5, 2004
  2. Replies:
    22
    Views:
    950
    Francis Glassborow
    Jan 24, 2006
  3. Replies:
    4
    Views:
    801
    Rolf Magnus
    May 17, 2006
  4. Arne Schmitz
    Replies:
    4
    Views:
    419
    Daniel Albuschat
    Jan 17, 2007
  5. Marcel Müller
    Replies:
    2
    Views:
    103
    Marcel Müller
    Mar 15, 2014
Loading...

Share This Page