【C++札记】多态

C++中多态是面向对象设计思想的重要特性,同名具有不同功能函数,该函数调用过程执行不同的功能。多态的原理是通过一张虚函数表(Virtual Table)实现的。动多态会牺牲一些空间和效率来最终实现动态绑定。

静多态

函数重载为静多态,绑定发生在编译期间,根据函数的参数来确定调用哪个函数。

#include <iostream>

using namespace std;

void foo(int a, int b)
{
    cout << "foo(int a, int b)" << endl;
}

void foo(double a, double b)
{
    cout << "foo(float a, float b)" << endl;
}

int main()
{
    foo(1, 2);
    foo(1.1, 2.2);

    return 0;
}

动多态

动多态不是在编译阶段决定的,而是在程序运行时根据基类的指针(引用)指向的对象来决定调用哪个类的虚函数。

动多态实现的条件:

1.基类中有虚函数。

2.派生类中重写基类中的虚函数。

3.父类的指针指向子类对象,调用共用的接口。

虚函数使用格式:

class 类名

{

    virtual 函数声明;

};
#include <iostream>

using namespace std;

class Animal
{
public:
    Animal()
    {
        cout << "Animal()" << endl;
    }

    virtual void eating()
    {
        cout << "animal is eating!" << endl;
    }

    virtual ~Animal()  //虚析构,保证析构完全
    {
        cout << "~Animal()" << endl;
    }
};

class Dog:public Animal
{
public:
    Dog()
    {
        cout << "Dog()" << endl;
    }

    void eating()
    {
        cout << "Dog is eating!" << endl;
    }

    ~Dog()
    {
        cout << "~Dog()" <<endl;
    }
};

int main()
{
    Animal *ani = new Dog;
    ani->eating();
    delete  ani;

    return 0;
}

注意:含有虚函数的类,析构函数也要声明为虚函数,为虚析构函数。如果上代码virtual ~Animal()改为~Animal(),运行结果如下:

明显析构不完全,虚析构可以调用派生类的析构函数,保证了完整析构。

纯虚函数

纯虚函数时在基类中声明的虚函数,没有实现体,在函数原型后加“=0”,使用格式:

class 类名
{

    virtual 函数声明 = 0;

};

1.含有纯虚函数的类称为纯虚基类,又称抽象基类(Abstract Base Class),抽象类不能进行实例化,可以继承,提供类的公共接口,在派生类中实现,类似java中Interface。

2.如果基类中声明了纯虚函数,派生类中没有实现该方法,则在派生类中仍然为纯虚函数,该派生类仍为纯虚基类。

#include <iostream>

using namespace std;

class Animal
{
public:
    Animal()
    {
        cout << "Animal()" << endl;
    }

    virtual void eating() = 0;

    virtual ~Animal()
    {
        cout << "~Animal()" << endl;
    }
};

class Dog:public Animal
{
public:
    Dog()
    {
        cout << "Dog()" << endl;
    }

    void eating()
    {
        cout << "Dog is eating!" << endl;
    }

    ~Dog()
    {
        cout << "~Dog()" <<endl;
    }
};

int main()
{
    Animal *ani = new Dog;
    ani->eating();
    delete  ani;

    return 0;
}
原文地址:https://www.cnblogs.com/woniu201/p/11109609.html