A little confusion about virtual functions

Started by
8 comments, last by fpsgamer 15 years, 10 months ago
So I'm a little confused on when to use virtual (in this particular case). I've seen class declarations like this:

class A {
virtual void Update() = 0;
};

class B : public A {
virtual void Update();
};


Aren't you supposed to include the virtual in the Update() declaration in class B if class B is defining an inherited virtual function? But, I've also seen this:

class A {
virtual void Update() = 0;
};

class B : public A {
void Update();
};


Notice there's no virtual here. So, what's the difference? Thanks. [Edited by - Shakedown on May 25, 2008 5:26:56 PM]
Advertisement
The virtual is implied by the fact that the superclass version is virtual. My own coding style is to always mark virtual functions as virtual. This is clearer IMO. This is a common, but my no means universal, style.
Once a function is marked virutal, it is always virtual. There is no way to un-virtualize it.
So it makes no difference to write this:
class B : public A {virtual void Update();};


Or this:
class B : public A {void Update();};


The only reason is for (human) clarity?
Quote:Original post by Shakedown
So it makes no difference to write this:
*** Source Snippet Removed ***

Or this:
*** Source Snippet Removed ***

The only reason is for (human) clarity?


Yes.
Quote:Original post by Shakedown
So it makes no difference to write this:
*** Source Snippet Removed ***

Or this:
*** Source Snippet Removed ***

The only reason is for (human) clarity?


Not at the moment, but in C++ standard revision virtual might be enforced to differentiate from shadowing.
Quote:Original post by Antheus
Quote:Original post by Shakedown
So it makes no difference to write this:
*** Source Snippet Removed ***

Or this:
*** Source Snippet Removed ***

The only reason is for (human) clarity?


Not at the moment, but in C++ standard revision virtual might be enforced to differentiate from shadowing.


Could you explain what shadowing is?
From a quick skim, this appears to explain it (though the author includes a poor example [sad]).

I believe that instead of doing as the author suggested (implementing the shadowed functions again and calling the super class versions), you can also write (following the awful example):
class B : public A {    // ...    using A::f;};
To shadow a member means to declare one in such a way that it hides one declared in outer scope:
struct A {	void foo(int x) {		std::cout << "A" << std::endl;	}};struct B : public A {	void foo(int x) {		std::cout << "B" << std::endl;	}};int main(int argc, char**argv) {	A a;	B b;	a.foo(10);	b.foo(20);	A * ap = new A();	A * bp = new B();	ap->foo(10);	bp->foo(20);}


Unlike virtual methods, foo() will not be disambiguated when calling it on ap or bp, since it's not a virtual method.

Another example:
void foo(){  int x = 10;  while (true) {    int x = 20;    std::cout << x;  }};


While not directly shadowing, and valid, x inside the loop hides the outer x. This is generally a bad practice.

Shadowing methods has (had) certain limited uses (Delphi had special OO concepts centered around them), but in general it will likely lead to confusion.
@rip-off & Antheus

Thanks (as usual) I learned something new from your replies :)

This topic is closed to new replies.

Advertisement