c++多态

1. 多态的基本概念 

多态” 指的是 同一名字的事物可以完成不同的功能

多态可以分为编译时的多态运行时的多态

编译时的多态:主要是指 函数的重载(包括运算符的重载)。对重载函数的调用,在编译时就能根据实参确定应该调用哪个函数,因此叫编译 时的多态;

运行时的多态:和继承、虚函数等概念有关。

有虚函数基类指针指向基类对象时就使用基类的成员指向派生类对象时就使用派生类的成员
这种就叫多态

 C++ 提供多态的目的是:可以通过基类指针对所有派生类的成员变量和成员函数进行 “全方位” 的访问。

2. 构成多态的条件 

  1. 必须存在继承关系;
  2. 继承关系中必须有同名的虚函数,并且它们是覆盖关系(函数原型相同)。
  3. 存在基类的指针,通过该指针调用虚函数。
#include<iostream>

using namespace std;

// Person类
class Person
{
public:
    Person(string name, int age) : name(name), age(age)
    {
    }
    virtual void info()
    {
        cout << "Call Person info, Name = " << this->name << " Age = " << this->age << endl;
    }

protected:
    string name;
    int age;
};
class Student : public Person
{
public:
    Student(string name, int age, float score) : Person(name, age), score(score)
    {
    }
    void info()
    {
        cout << "Call Student info, Name = " << this->name << " Age = " << this->age << " Score = " << score << endl;
    }

protected:
    float score;
};
int main()
{
    Person *person = new Person("zs", 20);
    person->info();
    person = new Student("ww", 21, 90);
    person->info();
    return 0;
}

3. 引用实现多态 

在 C++ 中,多态的实现,除了可以使用子类的指针指向父类的对象之外,还可以通过引用来实现多态,不过没有指针灵活。

    Person p1("地灵殿", 18);
    Student p2("恋恋", 18,99);

    Person &rPerson = p1;
    Person &sPerson = p2;

    rPerson.info();
    sPerson.info();

4. 虚函数 

使用 virtual 关键字修饰的函数 被称为虚函数。有虚函数才能实现多态。

什么时候声明虚函数:
        其一、成员函数的类会作为基类
        其二、成员函数希望在被继承后更改功能

语法:

virtual type funcName(plist){}

 

#include<iostream>

using namespace std;

class Animal{
    public:
    virtual void eat(){
        cout << "我是animal" << endl;
    }

};
class Dog:public Animal{
    public:
    void eat()
    {
        cout << "看是狗狗吃饭" << endl;
    }
};
class Cat:public Animal{
public:
    void eat()
    {
        cout << "看是猫猫吃饭" << endl;
    }
};

int main()
{
    Animal *pa = new Animal();
    pa->eat();
    pa = new Dog();
    pa->eat();
    pa = new Cat();
    pa->eat();

    return 0;
}

5. 虚析构 

c++的构造函数不能是虚函数,但析构函数可以被声明为虚构函数,有时候还必须被声明为虚构函数。用来做基类的类的析构函数一般都是虚函数。

 语法:

virtual ~FuncName() {}

#include<iostream>

using namespace std;

class Animal{
    public:
    virtual void eat(){
        cout << "我是animal" << endl;
    }
    virtual ~Animal() { cout << "我死啦" << endl; }
};
class Dog:public Animal{
    public:
    void eat()
    {
        cout << "看是狗狗吃饭" << endl;
    }
     ~Dog() { cout << "狗狗我死啦" << endl; }
};
class Cat:public Animal{
public:
    void eat()
    {
        cout << "看是猫猫吃饭" << endl;
    }
     ~Cat() { cout << "猫猫也没了" << endl; }
};

int main()
{
    Animal *pa = new Animal();
    pa->eat();
    pa = new Dog();
    pa->eat();
    pa = new Cat();
    pa->eat();
    delete pa;
    return 0;
}

6. 虚函数表 

虚函数是通过虚函数表来实现的,类包含虚函数表,对象包含虚指针,派生类会生成一个兼容基类的虚函数表。虚函数表中存储的是虚函数的地址。虚函数表在代码编译阶段就生成了。

7. C++如何实现动态绑定 

当编译器发现类中有虚函数的时候,编译器会创建一张虚函数表,把虚函数的函数入口地址放到虚函数表中, 并且在类中秘密增加一个指针,这个指针就是vpointer(缩写vptr), 这个指针是指向对象的虚函数表。在多态调用的时候,根据vptr指 针,找到虚函数表来实现动态绑定。

在对象构建的时候,vptr才指向虚函数表。子类继承基类时,子类会继承基类的vptr指针,这个vptr指针指向的是基类虚函数表,只有当子类创建对象时,之类的vptr指针指向子类的虚函数表。

8. 抽象基类和纯虚函数 

在类中加入一个纯虚函数就会变成抽象基类。纯虚函数在函数前加virtual在后面加上=0;

当继承一个抽象类时,必须实现所有的纯虚函数,否则继承出的类也将是一个抽象类。

语法:

纯虚函数:virtual type funcName(plist) = 0

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值