C++重载、重写、虚函数、多态

1.重载、重写、重定义


  重载:在同一个类中,函数名相同,参数列表不同,编译器会根据这些函数的不同参数列表,将同名的函数名称做修饰,从而生成一些不同名称的预处理函数,未体现多态。

  重写:子类重新定义父类中有相同名称相同参数的虚函数,主要是在继承关系中出现的,被重写的函数必须是virtual的,如果virtual函数是private的,子类中重写时改为public,protected也可以,体现了多态。(重写时子类函数可以不加virtual关键字,不过推荐加上)

  重定义:也叫隐藏,隐藏有两种形式:

    [1]派生类的函数与基类的函数完全相同(函数名和参数列表都相同),基类的函数没有使用virtual关键字。

    [2]派生类的函数和基类的函数同名,但参数列表不一样,在这种情况下,不管基类的函数声明是否有virtual关键字,基类的函数都将被隐藏。(注意这种情况与函数重载的区别,重载发生在同一个类中)

2.虚函数、多态


  C++的虚函数主要作用是“运行时多态”,关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。这种技术可以让父类的指针有“多种形态”。

  由于虚函数在运行时才确定,所以基类中所有的虚函数必须提供实现,而普通函数在不使用的情况下就不用实现。。

  因此说多态是根据虚函数实现的,因为如果函数不是虚函数(不加virtual关键字),则子类会把基类的函数隐藏,而加上virtual后父子类的函数可以共存。

  问题:

    问题1:C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。因此在派生类重新声明该虚函数时,可以加virtual,也可以不加,但习惯上一般在每一层声明该函数时都加virtual,使程序更加清晰。

  多态例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class A
{
public:
    virtual void disp(int n)
    {
        cout << "A::disp n=" << n << endl;
    }
};
class B : public A
{
public:
    void disp(int n)
    {
        cout << "B::disp n=" << n << endl;
    }
};
 
 
int main()
{
    A *p;
    A a;
    B b;
 
    // 多态
    p = &a;
    p->disp(1);
 
    p = &b;
    p->disp(1);
 
    return 0;
}

3.纯虚函数


  纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都必须要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”。

  引入纯虚函数的原因:在很多情况下,基类本身生成对象是不合情理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,但动物本身生成对象明显不合常理。

  声明了纯虚函数的类是一个抽象类。所以,用户不能创建类的实例,只能创建它的派生类的实例。

4.虚函数表


  都知道C++中的多态是用虚函数实现的: 子类覆盖父类的虚函数, 然后声明一个指向子类对象的父类指针, 如Base *b = new Derive(); 当调用b->f()时, 调用的是子类的Derive::f()。 

  这种机制内部由虚函数表实现,下面对虚函数表结构进行分析。

  包含虚函数的类才会有虚函数表, 同属于一个类的对象共享虚函数表, 但是有各自的_vptr,虚函数表实质是一个指针数组,里面存的是虚函数的函数指针。

 

 

 

 

 

posted on   能量星星  阅读(262)  评论(0编辑  收藏  举报

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示