The difference between overloading, rewriting (overwriting) and hiding in C + +

Posted by baccarak on Mon, 01 Nov 2021 07:44:21 +0100

Basic concepts:
Overload: it refers to several functions with the same name declared in the same accessible area with different parameter columns (different types, numbers and orders of parameters). It determines which function to call according to the parameter list. Overload does not care about the return type of the function.
Example:

class A{
public:
  void test(int i);
  void test(double i);//overload
  void test(int i, double j);//overload
  void test(double i, int j);//overload
  int test(int i);         //Error, non overloaded. Note that overloads do not care about function return types.
};

Hide: it means that the function of a derived class shields the base class function with the same name. Note that as long as the function with the same name, whether the parameter list is the same or not, the base class function will be hidden.

Example:

#include <iostream>
using namespace std;

class Base
{
public:
    void fun(double ,int ){ cout << "Base::fun(double ,int )" << endl; }
};

class Derive : public Base
{
public:
    void fun(int ){ cout << "Derive::fun(int )" << endl; }
};

int main()
{
    Derive pd;
    pd.fun(1);//Derive::fun(int )
    pb.fun(0.01, 1);//error C2660: "Derive::fun": the function does not accept 2 parameters

    system("pause");
    return 0;
}

Override (override): a redefined function exists in a derived class. The function name, parameter list and return value type must be consistent with the overridden function in the base class. Only when the function body is different (in curly braces), the rewritten function of the derived class will be called when the derived class is called, and the rewritten function will not be called. The overridden function in the overridden base class must have a virtual modifier.

Example:

#include<iostream>

using namespace std;

class Base
{
public:
    virtual void fun(int i){ cout << "Base::fun(int) : " << i << endl;}
};

class Derived : public Base
{
public:
    virtual void fun(int i){ cout << "Derived::fun(int) : " << i << endl;}
};
int main()
{
    Base b;
    Base * pb = new Derived();
    pb->fun(3);//Derived::fun(int)

    system("pause");
    return 0;
}

The difference between overloading and Rewriting:

(1) Scope difference: the rewritten and rewritten functions are in different classes, and the overloaded and overloaded functions are in the same class.

(2) Parameter difference: the parameter list of rewritten and rewritten functions must be the same, and the parameter list of overloaded and overloaded functions must be different.

(3) The difference between virtual: the rewritten base class must be modified by virtual. Overloaded functions and overloaded functions can be modified by virtual or not.

The difference between hiding and overriding and overloading:

(1) Different from overload scope: hidden functions and hidden functions are in different classes.

(2) Parameter difference: the parameter list of hidden function and hidden function can be the same or different, but the function name must be the same; When the parameters are different, whether the functions in the base class are modified by virtual or not, the base class functions are hidden rather than rewritten.

Example

#include <iostream>

using namespace std;

class Base
{
public:
    virtual void f(float x){ cout << "Base::f(float) " << x << endl; }
    void g(float x){ cout << "Base::g(float) " << x << endl; }
    void h(float x){ cout << "Base::h(float) " << x << endl; }
};

class Derived : public Base
{
public:
    virtual void f(float x){ cout << "Derived::f(float) " << x << endl; }
    void g(int x){ cout << "Derived::g(int) " << x << endl; }
    void h(float x){ cout << "Derived::h(float) " << x << endl; }
};

int main(void)
{
    Derived d;
    Base *pb = &d;
    Derived *pd = &d;
    // Good : behavior depends solely on type of the object
    pb->f(3.14f); //Derived::f(float) 3.14
    pd->f(3.14f); //Derived::f(float) 3.14

    // Bad : behavior depends on type of the pointer
    pb->g(3.14f); //Base::g(float) 3.14
    pd->g(3.14f); //Derived::g(int) 3

    // Bad : behavior depends on type of the pointer
    pb->h(3.14f); //Base::h(float) 3.14
    pd->h(3.14f); //Derived::h(float) 3.14

    system("pause");
    return 0;
}

(1) The function Derived::f(float) overrides Base::f(float).

(2) The function Derived::g(int) hides Base::g(float) instead of overloading.

(3) The function Derived::h(float) hides Base::h(float), not overrides.

Topics: C++ Back-end