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 <iostream>

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;
}

程序执行结果如下:
程序执行结果
若去掉基类func()成员函数前面的virtual,派生类func()会隐藏基类func(),但是派生类中的基类部分仍然有基类func()成员函数,只是对派生类对象隐藏了而已。所以若是通过指向派生类的基类指针调用func(),调用的应该是基类func(),结果如下:
程序执行结果

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

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;
}

执行结果:
这里写图片描述

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值