C++课程第五次博客——多态

多态性

Part1 多态性概述

多态是指一样的消息被不一样类型的对象接收时致使不一样的行为。在C++中,所谓信息是指对类的成员函数的调用,不一样的行为是指不一样的实现,也就是调用了不一样的函数。函数

1)多态的类型

分为四类:重载多态,强制多态,包含多态和参数多态。前二者为专用多态,然后者称为通用多态。this

2)多态的实现

分为两类:编译时的多态和运行时的多态。spa

前者是在编译的过程当中肯定了同名操做的具体操做对象设计

后者则是在程序运行过程当中才多态肯定操做所针对的具体对象指针

这种肯定操做的具体对象的过程就是绑定,绑定是指计算机程序自身彼此关联的过程,也就是把一条信息和一个对象相结合的过程。绑定工做在编译链接阶段完成的状况称为静态绑定,例如重载,强制和参数多态。而绑定工做在程序运行阶段完成的状况称为动态绑定,例如多态操做对象的肯定经过动态绑定完成。code

Part2 多态实验

在多态性中,运算符重载、虚函数、纯虚函数和抽象类是相对来讲难以理解的,下面咱们主要将对这些知识点,设计实验并探索。对象

运算符重载

第一注意点blog

当运算符重载为类的成员函数时,函数的参数个数比原来的操做数个数要少一个(后置“++”,“--”除外)接口

#include <iostream>
using namespace std;
class fun{
private:
    double x,y;
public:
    fun(double x=0,double y=0):x(x),y(y){};
    fun operator+(const fun &c1,const fun &c2)const;   //当重载函数为重载函数时,传进两个无名对象
    void displat()const;
};

结果编译器直接报错:Overloaded 'operator+' must be a unary or binary operator (has 3 parameters)

当operator+改为只传进一个参数时,编译经过。

缘由:类的this指针所指的对象默认穿进去。

虚函数

虚函数是动态绑定的基础。虚函数必须是非静态的成员函数。虚函数通过派生以后,在类族中就能够实现运行过程当中的多态

第二注意点:

由成员函数来调用或者是经过指针、引用来访问虚函数

#include <iostream>
using namespace std;
//类的声明和实现
class base1{
public:
    virtual void display()const;        //虚函数
};
void base1::display() const{
    cout<<"Base1::display"<<endl;
}
class base2:public base1{
public:
    void display() const;
};
void base2::display()const{
    cout<<"base2::display"<<endl;
}
class Derived:public base2{
public:
    void display() const;
};
void Derived::display()const{
    cout<<"Derived::display"<<endl;
}
//经过对象名来访问虚函数
int main(){
    base1 base1;
    base2 base2;
    Derived derived;
    base1.display();
    base2.display();
    derived.display();
    return 0;
}

结果输出正确:

可是用这个方式来访问虚函数,则是绑定在编译过程当中,而不是在运行过程当中进行。若是要实现多态绑定,须要用指针,使程序更加灵活。

void fun(base1 *ptr){
    ptr->display();
}

纯虚函数和抽象类

带纯虚函数的类是抽象类,抽象类声明了一个类族派生类的共同接口,而接口的完整实现,即纯虚函数的函数体,要由派生类本身定义。

#include <iostream>
using namespace std;
class base1{
public:
    virtual void display()const=0;        //纯虚函数
};
class base2:public base1{
public:
    void display1() const;                              //没有去定义抽象的函数体
};
void base2::display1()const{
    cout<<"base2::display1"<<endl;
}

报错:Out-of-line definition of 'display1' does not match any declaration in 'base2'

将display1修改成display编译经过。

并且在程序中的虚函数并无用virtual关键字显性声明,二是编译器经过派生类有着与抽象基类的纯虚函数相同的名称、参数以及返回值,来自动肯定其为虚函数。

Part3 总结

经过定义同一名称操做,当面对不一样数据时实现不一样的功能。使程序的功能实现更加灵活。

相关文章
相关标签/搜索