Overloading and Overriding Are Different



Item 21. Overloading and Overriding Are Different

Overloading and overriding have nothing whatsoever to do with each other. Nothing. They are entirely different concepts. Ignorance of this difference, or simply sloppy use of terminology, has caused untold confusion and given rise to countless bugs.

Overloading occurs when two or more functions in the same scope have the same name and different signatures. A function's signature consists of the number and type of its declared arguments (otherwise known as "formal" arguments). When the compiler looks up a function name and finds more than one function with that name in a scope, it selects among the available candidates in that scope for the one whose formal arguments best match the actual arguments of the function call (see also Member Function Lookup [24, 87] and Argument Dependent Lookup [25, 89]). That's overloading.

Overriding occurs when a derived class function has the same name and signature as a base class virtual function. In that case, the implementation of the derived class function will replace that of the inherited base class function for virtual calls to a derived object. Overriding changes the behavior of a class but not its interface (but see Covariant Return Types [31, 107]).

Consider the following simple base class:

class B {
  public:
    //...
    virtual int f( int );                                                
    void f( B * );                                                       
    //...
};

The name f is overloaded in B because two different functions named f are in the same scope. (The overloading is highlighted as bad code for two reasons. You probably don't want to overload a virtual function, and you probably don't want to overload on both an integral and a pointer type. See C++ Gotchas and Effective C++, respectively, to see why.)

class D : public B {
  public:
    int f( int );
    int f( B * );
};

The member function D::f(int) overrides the base class virtual function B::f(int). The member function D::f(B *) doesn't override anything, because B::f(B *) is not virtual. It does, however, overload D::f(int). Note that it does not overload the base class members B::f, because it's in a different scope (see also Optional Keywords [63, 231]).

Overloading and overriding are different concepts, and a technical understanding of their differences is essential if you want to grok advice on advanced base class interface design.