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

  • Thread starter Philippe Guglielmetti
  • Start date
P

Philippe Guglielmetti

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 ?
 
R

Ron Natalie

Philippe Guglielmetti said:
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"; }};
^
 
V

Victor Bazarov

Philippe Guglielmetti said:
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
 
V

Victor Bazarov

Ron Natalie said:
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
 

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

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top