C++基础-重载/重写/重定义/多态

1. 重载(overload)

  • 定义

    • 在一个类内,如果存在若干个同名函数,而且这些函数之间可以用形参个数形参类型区分开来的时候(注意不能靠函数返回类型区分),这几个函数就互为重载函数
  • 注意点

    • 重载发生在类内,不会发生在基类和派生类之间

    • 函数名必须相同,形参个数或类型可以不同

    • 重载函数之间必须依靠形参个数形参类型来进行区分,不能依靠返回类型

      • 如果两个函数同名同参,但返回类型不同,编译器会因为二义性而报错
    • 重载调用:通过类对象调用重载函数时,编译器通过传递的实参个数类型去匹配相应的函数,而不会发生歧义。

      • 体现了重载的作用:可以使用若干个同名函数
    • 虚函数和普通函数之间也可以重载


2. 重写(override,覆盖)

  • 定义

    • 重写也称为覆盖,重写了一个方法以实现不同功能。一般用于子类继承父类时,重写父类中的方法。函数特征相同,具体实现不同。
  • 注意点

    • 重写只能出现在基类和派生类之间,当

      • [1] 基类和派生类之间存在同名函数
      • [2] 返回类型、形参个数和类型完全相同
      • [3] 基类中的该函数必须是virtual(派生类中virtual可有可无)
    • 则派生类中的该函数覆盖掉基类中的该函数,此性质用来实现多态

    • 重写函数的访问修饰符可以不同,即使virtual是private的,派生类中改为public或protected也可以


3. 重定义(redefining,隐藏)

  • 定义

    • 重定义也称为隐藏,派生类对基类成员函数重新定义,即派生类定义了某个函数,该函数与基类中函数同名
  • 注意点

    • 重定义也只能出现在基类和派生类之间,当

      • [1] 基类和派生类之间存在同名函数
      • [2] 无论返回类型、形参个数和类型是否相同
    • 则基类中的同名函数都会被隐藏

      • 如果基类中该函数被重载,则重载函数都会被隐藏,包括虚函数
    • 如果返回类型、形参个数和类型均相同,且基类中为virtual函数,则属于重写

    • 如果要访问基类的该函数,需要在函数名前加上作用域操作符


4. 多态(polymorphism)

  • 定义

    • 多态是面向对象思想的精髓所在,使用多态是为了避免在父类中大量重载而引起代码臃肿和难于维护

    • 关于多态,一种不严谨的说法是:继承是子类使用父类的方法,多态是父类使用子类的方法

  • 多态的分类

    多态可以分为两类:静态多态性 + 动态多态性

    • [1] 静态多态性:又称编译时的多态性,静态多态性是通过函数的重载实现

      • 函数重载运算符重载实现的多态性属于静态多态性,在程序编译时就能决定调用哪个函数
    • [2] 动态多态性:又称运行时的多态性,动态多态性是通过虚函数实现的。

      • 程序运行过程中才动态地确定操作所针对的对象
  • 注意点

    虚函数存在的唯一目的就是为了实现多态,成员函数要以多态的形式来执行,那么必须满足

    • (1) 基类中这些成员函数为虚函数,并必须实现
    • (2) 派生类中这些成员函数必须被重写同名 + 同返回同形参个数和类型 + 基类中为virtual
    • (3) 将派生类的对象赋给基类的指针变量或引用,可用基类的指针或引用调用派生类的方法

    实现多态,上述三个条件必须完全满足,虚函数的特性才能完全发挥出来,也才能实现多态。

  • 不是多态的例子

    • [1] 派生类和基类都是虚函数,派生类中与基类函数同名,形参个数类型与基类中不同,这种情况属于隐藏不会报错

      • 如果形参的个数和类型相同,返回类型也必须相同,否则编译会报错,因为返回类型发生了冲突,隐藏发生错误
    • [2] 基类中是虚函数,派生类中不是虚函数,派生类中与基类函数同名,返回类型形参个数类型与基类不同,这种情况也属于隐藏,如果返回类型、形参个数和类型均相同,这种情况属于重写不会报错

    • [3] 基类中不是虚函数,派生类中是虚函数,或基类派生类中均不是虚函数,派生类中与基类函数同名,这种情况属于隐藏,同样也不会报错


附:实例说明

  • [1] 重载,重写,重定义
#include <iostream>
using namespace std;

class BasicClass
{
    private:
        int a;
    public:
        //函数重载实例
        void overloadFunc(int k)
        {
            cout<<"overloadFunc single parameter:"<<k<<endl;
        }

        void overloadFunc(int k,int t)
        {
            cout<<"overloadFunc two parameters:"<<" k:"<<k<<" t:"<<t<<endl;
        }

        virtual void overrideFunc()
        {
            cout<<"override fun from basic class!"<<endl;
        }
};


class DeriveClass : public BasicClass
{
    private:
    public:
        //重定义:隐藏
        void overloadFunc(int k)
        {
            cout<<"redefine overloadFunc from derived Class!"<<endl;
        }
        //重写
        void overrideFunc()
        {
            cout<<"override from derived class!"<<endl;
        }
};


int main()
{
    BasicClass a;
    DeriveClass b;

    //重载调用
    cout<<"重载调用"<<endl;
    a.overloadFunc(1);
    a.overloadFunc(1,2);              //根据形参来区分调用哪个函数

    //重写
    cout<<endl;
    cout<<"重写-该性质可实现多态"<<endl;
    b.overrideFunc();
    a.overrideFunc();

    //隐藏
    cout<<endl;
    cout<<"重定义/隐藏"<<endl;
    a.overloadFunc(1);
    b.BasicClass::overloadFunc(1);     //重定义时可以通过作用域操作符访问基类函数
    b.overloadFunc(1);
    return 0;
}
  • [2] 多态
#include <iostream>
using namespace std;

class A
{
    public:
        virtual void test(int a)
        {
            cout<<"basic class A: "<<a<<endl;
        }
};

class B: public A
{
    public:
        void test(int b)         //重写-覆盖
        {
            cout<<"derived class B: "<<b<<endl;
        }
};

class C: public A
{
    public:
        void test(int c)
        {
            cout<<"derived class C: "<<c<<endl;
        }
};

int main()
{
    A *a0;          //指针
    B b;
    C c;
    A &a1 = b;      //引用
    A &a2 = c;

    a0 = &b;
    a0->test(2);   //调用类B的test函数

    a0 = &c;
    a0->test(3);   //调用类C的test函数

    a1.test(4);    //调用类B的test函数
    a2.test(5);    //调用类C的test函数

    return 0;
}



Acknowledgements:
http://www.cnblogs.com/DannyShi/p/4593735.html
http://www.cnblogs.com/liangning/p/3968151.html
http://blog.csdn.net/loverooney/article/details/38307523

2017.09.26

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值