virtual function specifier

From cppreference.com
 
 
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements
Jump statements
Functions
function declaration
lambda function declaration
function template
inline specifier
exception specifications (deprecated)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
decltype specifier (C++11)
Specifiers
cv specifiers
storage duration specifiers
constexpr specifier (C++11)
auto specifier (C++11)
alignas specifier (C++11)
Initialization
Literals
Expressions
alternative representations
Utilities
Types
typedef declaration
type alias declaration (C++11)
attributes (C++11)
Casts
implicit conversions
const_cast conversion
static_cast conversion
dynamic_cast conversion
reinterpret_cast conversion
C-style and functional cast
Memory allocation
Classes
Class-specific function properties
virtual function
override specifier (C++11)
final specifier (C++11)
Special member functions
Templates
class template
function template
template specialization
parameter packs (C++11)
Miscellaneous
Inline assembly
 

Specifies that a function is virtual

Contents

[edit] Syntax

virtual function_declaration ;

[edit] Explanation

Virtual functions are member functions whose behavior can be overridden in derived classes. As opposed to non-virtual functions, the overridden behavior is preserved even if there is no compile-time information about the actual type of the class. That means, even if a derived class is handled using pointer or reference to the base class, a call to a overridden virtual function would invoke the behavior defined in the derived class.

The function signature must be the same in order to be overridden.

The return type of a overriding virtual function doesn't necessarily need to be the identical to that of the overridden function. The types can be different if they are covariant with each another. Two types are covariant if they satisfy the following requirements:

Here we refer to the overriding function as Derived::f() and to the overridden function as Base::f()
  • both types are pointers or references to classes. Multi-level pointers or references are not allowed.
  • the class of the return type of Base::f() must be a unambiguous and accessible direct or indirect base class of the class of the return type of Derived::f().
  • the return type of Derived::f() must be equally or less cv-qualified than the return type of Base::f().

If a virtual function is called directly, that is, explicitly qualifying the class it is a member of, then the virtual call mechanism is suppressed and that particular implementation is called.

A virtual destructor of a base class is always overridden by a destructor of a derived class, even though that destructors are otherwise not inherited.

The access rules to a virtual function are determined by the first declaration. Access rules defined by the declarations of the overriding functions apply only to the direct function calls.

virtual function specifier implies membership, thus only member functions can be virtual. Also, since an instance of a class is needed in order to call a virtual function, virtual function can not be static.

Functions templates cannot be declared virtual. This applies only to functions that are themselves templates - a regular member function of a class template can be declared virtual.

[edit] Example

class Parent {
public:
    void functionA();
    virtual void functionB();   //Note the keyword virtual
    void functionC();
};
 
class Child : public Parent {
public:
    void functionA();
    virtual void functionB();   //Note the keyword virtual
};
 
int main()
{
    Parent* p1 = new Parent;
    Parent* p2 = new Child;
    Child* c = new Child;
 
    p1->functionA();   //Calls Parent::functionA
    p1->functionB();   //Calls Parent::functionB
    p1->functionC();   //Calls Parent::functionC
 
    p2->functionA();   //Calls Parent::functionA because p2 points to a Parent
    p2->functionB();   //Calls Child::functionB even though p2 points 
                       // to a Parent because functionB is virtual
    p2->functionC();   //Calls Parent::functionC
 
    c->functionA();   //Calls Child::functionA
    c->functionB();   //Calls Child::functionB
    c->functionC();   //Calls Parent::functionC
 
    return 0;
}


[edit] See also