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


    多态性

    Part1 多态性概述

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

    1)多态的类型

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

    2)多态的实现

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

    前者是在编译的过程中确定了同名操作的具体操作对象

    后者则是在程序运行过程中才多态确定操作所针对的具体对象

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

    Part2 多态实验

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

    运算符重载

    第一注意点

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

    #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 总结

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

  • 相关阅读:
    文本框只能填数字
    Win7 IIS 配置错误:不能在此路径中使用此配置节。如果在父级别上锁定了该节,便会出现这种情况。锁定是默认设置的
    C#中小数点后保留两位小数,四舍五入的函数及使用方法(转)
    数据库中where与having区别
    NET Runtime version 2.0.50727.42
    C盘文件过大,C盘空间莫名丢失,pagefile.sys文件
    VS2008水晶报表变两页(重装系统后)
    win8 IIS配置
    从程序员到项目经理(5):程序员加油站 -- 懂电脑更要懂人脑
    从程序员到项目经理(4):程序员加油站 -- 不是人人都懂的学习要点
  • 原文地址:https://www.cnblogs.com/codingbyjusticexu/p/11737147.html
Copyright © 2020-2023  润新知