C++ 重载、重写、重定义

重载

  • 同一个类中的同名函数会重载;
  • 重载函数的函数名相同,参数不同,不能用返回值判断是否是函数重载;
  • 在不同类中的同名函数不是重载。

下面两函数为函数重载

void func()
    {
        std::cout << "调用了基类的func()" << std::endl;
    }

    void func(int a)
    {
        std::cout << "调用了基类的func(int)" << std::endl;
    }

重写

  • 重写发生在派生类和基类之间;
  • 若派生类和基类有函数原型相同的成员函数,并用virtual关键字声明(基类成员函数用virtual关键字声明即可,而不管派生类成员函数是否用virtual关键字声明),则此成员函数为重写;
  • 若派生类和基类有函数原型相同的成员函数,但没有用virtual关键字声明,则为重定义;
  • 重写的派生类成员函数会覆盖与原型相同的基类成员函数。

重定义

  • 重定义发生在派生类和基类之间;
  • 若派生类和基类有函数原型相同的成员函数,但没有用virtual关键字声明,则派生类成员函数为重定义;
  • 若派生类和基类有函数名相同但参数不同的成员函数,则派生类成员函数为重定义;
  • 重定义的派生类成员函数会隐藏相应的基类成员函数。

下面派生类的func()成员函数为对基类func()成员函数的重写,而派生类的func()成员函数为对基类func(int)成员函数的重定义。所以派生类的func()成员函数会覆盖基类func()成员函数,派生类的func()成员函数会隐藏基类func(int)成员函数。

class Parent
{
public:
    void func()
    {
        std::cout << "调用了基类的func()" << std::endl;
    }

    void func(int a)
    {
        std::cout << "调用了基类的func(int)" << std::endl;
    }
};

class Child : public Parent
{
    void func()
    {
        std::cout << "调用了派生类的func()" << std::endl;
    }

    void func1()
    {
        std::cout << "调用了派生类的func1()" << std::endl;
    }
};

完整代码如下:

#include 

class Parent
{
public:
    virtual void func()
    {
        std::cout << "调用了基类的func()" << std::endl;
    }

    void func(int a)
    {
        std::cout << "调用了基类的func(int)" << std::endl;
    }
};

class Child : public Parent
{
public:
    void func()
    {
        std::cout << "调用了派生类的func()" << std::endl;
    }

    void func1()
    {
        std::cout << "调用了派生类的func1()" << std::endl;
    }
};

int main()
{
    Child child1;
    Parent * parent1 = &child1;//parent1指向child1的基类部分,所以只能调用其基
                               //类部分成员函数
    parent1->func();//因为func()声明为虚函数,所以派生类func()会覆盖基类
                    //func(),故调用派生类func()

    return 0;
}

程序执行结果如下:
C++ 重载、重写、重定义_第1张图片
若去掉基类func()成员函数前面的virtual,派生类func()会隐藏基类func(),但是派生类中的基类部分仍然有基类func()成员函数,只是对派生类对象隐藏了而已。所以若是通过指向派生类的基类指针调用func(),调用的应该是基类func(),结果如下:
C++ 重载、重写、重定义_第2张图片

覆盖和隐藏

  • 覆盖
    当派生类和基类函数原型相同的成员函数声明为虚函数时,派生类的成员函数会覆盖基类的成员函数。(会覆盖函数原型相同的成员函数,对函数原型不同,函数名相同的成员函数会覆盖)
  • 隐藏
    当派生类和基类函数原型相同的成员函数没有声明为虚函数时,派生类的成员函数会隐藏基类的成员函数(会隐藏函数名相同的成员函数)。
#include 

class Parent
{
public:
    virtual void func()//声明为虚函数
    {
        std::cout << "调用了基类的func()" << std::endl;
    }

    void func(int a)
    {
        std::cout << "调用了基类的func(int)"
                  << "参数为:" << a << std::endl;
    }
};

class Child : public Parent
{
public:
    void func()
    {
        std::cout << "调用了派生类的func()" << std::endl;
    }

    void func1()
    {
        std::cout << "调用了派生类的func1()" << std::endl;
    }
};

int main()
{
    Child child1;
    child1.func();//func()声明为虚函数时,派生类func()会覆盖基类func()
                  //所以会调用派生类func()
    child1.Parent::func();//因为基类func()只是被派生类func()覆盖了,
                          //而不是消失了,派生类仍然继承了基类的func(),
                          //所以可以显示地调用基类func()
    child1.Parent::func(10);//基类func(int)只是被派生类func(int)隐藏,
                            //但基类fun(int)仍然存在,派生类仍然继承了基类的func(int),
                            //所以可以显示地调用基类func(int)

    return 0;
}

执行结果:
C++ 重载、重写、重定义_第3张图片

你可能感兴趣的:(C++ 重载、重写、重定义)