What does the keyword virtual do when overriding a method? I\'m not using it and everything works fine.
Does every compiler behave the same in this
A virtual
method in the base class will cascade through the hierarchy, making every subclass method with the same signature also virtual
.
class Base{
public:
virtual void foo(){}
};
class Derived1 : public Base{
public:
virtual void foo(){} // fine, but 'virtual' is no needed
};
class Derived2 : public Base{
public:
void foo(){} // also fine, implicitly 'virtual'
};
I'd recommend writing the virtual
though, if for documentation purpose only.
When a function is virtual, it remains virtual throughout the hierarchy, whether or not you explicitly specify each time that it is virtual. When overriding a method, use virtual in order to be more explicit - no other difference :)
class A
{
virtual void f()
{
/*...*/
};
};
class B:public A;
{
virtual void f() //same as just void f()
{
/*...*/
};
};
You cannot override a member function without it.
You can only hide one.
struct Base {
void foo() {}
};
struct Derived : Base {
void foo() {}
};
Derived::foo
does not override Base::foo
; it simply hides it because it has the same name, such that the following:
Derived d;
d.foo();
invokes Derived::foo
.
virtual
enables polymorphism such that you actually override functions:
struct Base {
virtual void foo() {}
};
struct Derived : Base {
virtual void foo() {} // * second `virtual` is optional, but clearest
};
Derived d;
Base& b = d;
b.foo();
This invokes Derived::foo
, because this now overrides Base::foo
— your object is polymorphic.
(You also have to use references or pointers for this, due to the slicing problem.)
Derived::foo
doesn't need to repeat the virtual
keyword because Base::foo
has already used it. This is guaranteed by the standard, and you can rely on it. However, some think it best to keep that in for clarity.Extending on Light Races answer, maybe this will help some people to see what it is doing.
struct Base {
public:
void foo() {
printf_s("Base::foo\n");
}
};
struct Derived : Base {
void foo() {
printf_s("Derived::foo\n");
}
};
struct BaseVirtual {
public:
virtual void foo() {
printf_s("BaseVirtual::foo\n");
}
};
struct DerivedVirtual : BaseVirtual {
virtual void foo() {
printf_s("DerivedVirtual::foo\n");
}
};
Derived d;
d.foo(); // Outputs: Derived::foo
Base& b = d;
b.foo(); // Outputs: Base::foo
DerivedVirtual d2;
d2.foo(); // Outputs: DerivedVirtual::foo
BaseVirtual& b2 = d2;
b2.foo(); // Outputs: DerivedVirtual::foo