overriding static and virtual members with same proto. What is the standard ?

Discussion in 'C++' started by Philippe Guglielmetti, Oct 22, 2003.

  1. Look at these few lines of code:

    class A { public: virtual void f() { cout << "A";}};
    class B : public A{public: static void f() { cout << "B"; }};
    class C : public B{public: void f() { cout << "C"; }}; // virtual or not ?
    that's the question...

    int main(int, char**)
    {
    A* x; A a; B b; C c;
    a.f(); b.f(); c.f();
    x = &a; x->f(); x = &b; x->f(); x = &c; x->f();
    }

    Borland C++ 5.5 outputs "ABCAAA"
    MS VC6 and 7 give "ABCAAC"

    my explanation is that C::f overrides the virtual A::f with VC,
    while C::f overrides the static B::f with BC5. In fact, if C is redefined as

    class C : public B{public: virtual void f() { cout << "C"; }};

    then BC5 behaves as VC

    Questions:
    1) what does the standard say? (I was unable to find a clear answer..)
    2) what is the reason for allowing the above code to compile without even a
    warning ?

    --
    Philippe Guglielmetti - www.dynabits.com
     
    Philippe Guglielmetti, Oct 22, 2003
    #1
    1. Advertising

  2. Philippe Guglielmetti

    Ron Natalie Guest

    "Philippe Guglielmetti" <> wrote in message news:3f9699a8$0$3677$...
    > Look at these few lines of code:
    >
    > class A { public: virtual void f() { cout << "A";}};
    > class B : public A{public: static void f() { cout << "B"; }};
    > class C : public B{public: void f() { cout << "C"; }}; // virtual or not ?
    > that's the question...


    Both compilers are wrong. The program is ILL-FORMED. The
    rules say that a member function that is the same name and parameters
    as a virtual function in the base is also virtual (10.3/2) and static
    members shall NOT be declared virtual (9.4.1 / 2)

    Comeau catches the erorr

    "ComeauTest.c", line 2: error: only nonstatic member functions may be virtual
    class B : public A{public: static void f() { cout << "B"; }};
    ^
     
    Ron Natalie, Oct 22, 2003
    #2
    1. Advertising

  3. "Philippe Guglielmetti" <> wrote...
    > Look at these few lines of code:
    >
    > class A { public: virtual void f() { cout << "A";}};
    > class B : public A{public: static void f() { cout << "B"; }};
    > class C : public B{public: void f() { cout << "C"; }}; // virtual or not ?
    > that's the question...
    >
    > int main(int, char**)
    > {
    > A* x; A a; B b; C c;
    > a.f(); b.f(); c.f();
    > x = &a; x->f(); x = &b; x->f(); x = &c; x->f();
    > }
    >
    > Borland C++ 5.5 outputs "ABCAAA"
    > MS VC6 and 7 give "ABCAAC"
    >
    > my explanation is that C::f overrides the virtual A::f with VC,


    Yes (10.3/2).

    > while C::f overrides the static B::f with BC5.


    That's, I am sorry, nonsense. It's an apparent bug in BC5.

    > In fact, if C is redefined as
    >
    > class C : public B{public: virtual void f() { cout << "C"; }};
    >
    > then BC5 behaves as VC


    That should be of no difference. Whether 'f' is declared virtual
    or not in C, it should be considered overriding A::f _simply_because_
    they have the same signature and A::f is virtual.

    >
    > Questions:
    > 1) what does the standard say? (I was unable to find a clear answer..)


    B::f hides A::f. If you try to access 'f' using a reference to B
    or a pointer to B, the compiler should use B::f (10.2/2).

    C::f in turn hides B::f _and_ overrides A::f. That means that if
    you access 'f' using a reference to A or a pointer to A, but the
    object is really a C, the C::f should be called.

    > 2) what is the reason for allowing the above code to compile without even

    a
    > warning ?


    There is no requirement in the standard to issue any diagnostic
    when compiling a well-formed program, IIRC.

    Victor
     
    Victor Bazarov, Oct 22, 2003
    #3
  4. "Ron Natalie" <> wrote...
    >
    > "Philippe Guglielmetti" <> wrote in message

    news:3f9699a8$0$3677$...
    > > Look at these few lines of code:
    > >
    > > class A { public: virtual void f() { cout << "A";}};
    > > class B : public A{public: static void f() { cout << "B"; }};
    > > class C : public B{public: void f() { cout << "C"; }}; // virtual or not

    ?
    > > that's the question...

    >
    > Both compilers are wrong. The program is ILL-FORMED. The
    > rules say that a member function that is the same name and parameters
    > as a virtual function in the base is also virtual (10.3/2) and static
    > members shall NOT be declared virtual (9.4.1 / 2)
    >
    > Comeau catches the erorr
    >
    > "ComeauTest.c", line 2: error: only nonstatic member functions may be

    virtual
    > class B : public A{public: static void f() { cout << "B"; }};


    How about that!

    I always thought that static and non-static members had different
    number of arguments due to the hidden argument, the "this" pointer.
    You made me look more carefully at this and I discovered 13.1 where
    the Standard says that names cannot be overloaded if the only
    difference between them is that one is static and the other is not.

    HOWEVER... B::f does not _overload_ A::f, it _hides_ it (different
    scope).

    Now, I cannot find a direct confirmation in the Standard of either
    point of view. If you could elaborate on your quotes (for all I
    know you 9.4.1/2 refers to the fact that 'virtual' and 'static'
    cannot appear in the same member function declaration), I'd really
    appreciate it.

    It would be nice to hear from Greg Comeau as well.

    Victor
     
    Victor Bazarov, Oct 22, 2003
    #4
    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. JFCM
    Replies:
    4
    Views:
    5,767
  2. greg
    Replies:
    15
    Views:
    586
    Greg Ewing
    Sep 10, 2004
  3. =?ISO-8859-2?Q?Przemys=B3aw_Staniszewski?=

    Ethernet and TCP/IP proto in vhdl

    =?ISO-8859-2?Q?Przemys=B3aw_Staniszewski?=, Sep 29, 2006, in forum: VHDL
    Replies:
    8
    Views:
    12,832
    alainsan
    Aug 12, 2011
  4. ian

    Proto Question

    ian, Nov 6, 2006, in forum: C Programming
    Replies:
    2
    Views:
    412
    Richard Bos
    Nov 6, 2006
  5. Hal Vaughan
    Replies:
    2
    Views:
    352
    James Kanze
    Mar 14, 2008
Loading...

Share This Page