C++第八章:多态性

一、多态性概述

面向对象的多态性可以分为4类:重载多态、强制多态、包含多态和参数多态。前面两种统称为专用多态,而后面两种称为通用多态。

包含多态 是类族中定义于 不同类中的 同名成员函数 的多态行为,主要是通过虚函数来实现。

多态的实现

多态从实现的角度来讲可以划分为两类:编译时的多态和运行时的多态。

绑定是指计算机程序自身彼此关联的过程,就是把一条消息和一个对象的方法相结合的过程。绑定工作在编译连接阶段完成的情况称为静态绑定;绑定工作在程序运行阶段完成的情况称为动态绑定。

二、运算符重载

运算符重载是对已有的运算符赋予多重含义,使同一个运算符作用于不同类型的数据时导致不同的行为。

运算符重载的实质就是函数重载。

运算符重载的规则

规则如下:

  1. ++中的运算符除了少数几个之外,全部可以重载,而且只能重载C++中已经有的运算符。
  2. 重载之后运算符的优先级和结合性都不会改变。
  3. 重载的功能应当与原有功能相类似,不能改变原运算符的操作对象个数,同时至少要有一个操作对象是自定义类型。

运算符的重载形式有两种,即重载为类的非静态成员函数和重载为非成员函数。运

算符重载为类的成员函数的一般语法形式为:

cpp 复制代码
返回类型 operator运算符(形参表)
{
    函数体
}

运算符重载为非成员函数的一般语法形式为:

cpp 复制代码
返回类型 operator运算符(形参表)
{
    函数体
}

返回类型 指定了重载运算符的返回值类型,也就是运算结果类型;operator 是定义运算符重载函数的关键字;运算符 即是要重载的运算符名称,必须是C++中可重载的运算符,比如要重载加法运算符,这里就写"十";形参表中给出重载运算符所需要的参数和类型。

在C++中,operator 运算符 ---> 函数

cpp 复制代码
operator +

例子:复数相加

cpp 复制代码
#include <iostream>

using namespace std;

class Complex
{
public:
    Complex(double r, double i) : real(r), imag(i){}
    void show() const {cout << real << " + " << imag << "i" << endl;}
    Complex operator +(const Complex &other) const
    {
        Complex ret(this->real + other.real, this->imag + other.imag );
        return ret;
    }

private:
    double real, imag;
};

int main()
{
    Complex c1(1,2);
    c1.show();
    Complex c2(2,3);
    c2.show();

    (c1+c2).show();//c1.operator +(c2).show();

    cout << "Hello World!" << endl;
    return 0;
}

当以非成员函数形式重载运算符时,有时需要访问运算符参数所涉及类的私有成员,这时可以把该函数声明为类的友元函数。

or 友元函数

++前 后++

效率:++i > ++i

三、虚函数

虚函数声明只能出现在类定义中的函数原型声明中,而不能在成员函数实现的时候。

通过指针引用访问虚函数。

例子:选择英雄

cpp 复制代码
#include <iostream>
#include <cstdlib>
#include <cstring>
using namespace std;

class Hero
{
public:
    virtual void q(){}
};

class HY : public Hero
{
    void q() {cout << "the last sun" << endl;}

};

class ZZ : public Hero
{
    void q() {cout << "i am butterfly" << endl;}

};

class WZJ : public Hero
{
    void q() {cout << "the ice" << endl;}

};

int main()
{
    Hero *p;
    int n = 0;

    cin >> n;
    if (n == 1)
    {
        p = new HY;
    }
    else if (n == 2)
    {
        p = new ZZ;
    }
    else
    {
        p = new WZJ;
    }

    p->q();
    return 0;
}

虚表

  1. 吸收基类成员----继承
  2. 改造基类成员----覆盖
  3. 添加基类成员
  4. 如果派生类的某函数,在基类没有相应的同名、同形参的函数,该函数被编译时会报错;++(如:基类不含fn7 fn8 ,所以调用这两个函数时,编译报错)++
  • 全局函数不能为虚函数;
  • 静态函数不能为虚函数;
  • 构造函数不能为虚函数。

虚析构函数

虚析构函数的声明语法为:

cpp 复制代码
virtual ~类名();

如果一个类的析构函数是虚函数,那么由它派生而来的所有子类的析构函数也是虚函数。

如果有可能通过基类指针调用对象的析构函数(通过delete),就需要让基类的析构函数成为虚函数,否则会产生不确定的后果。

四、纯虚函数与抽象类

纯虚函数的声明格式为:

cpp 复制代码
virtual 函数类型 函数名(参数表)=0;

实际上,它与一般虚函数成员的原型在书写格式上的不同就在于后面加了"=0"。声明为纯虚函数之后,基类中就可以不再给出函数的实现部分。纯虚函数的函数体由派生类给出。
部分是纯虚函数就是抽象类

全部都是纯虚函数 就是接口类

相关推荐
2401_857439692 小时前
SSM 架构下 Vue 电脑测评系统:为电脑性能评估赋能
开发语言·php
SoraLuna3 小时前
「Mac畅玩鸿蒙与硬件47」UI互动应用篇24 - 虚拟音乐控制台
开发语言·macos·ui·华为·harmonyos
xlsw_3 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
Dream_Snowar4 小时前
速通Python 第三节
开发语言·python
唐诺4 小时前
几种广泛使用的 C++ 编译器
c++·编译器
高山我梦口香糖5 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
冷眼看人间恩怨5 小时前
【Qt笔记】QDockWidget控件详解
c++·笔记·qt·qdockwidget
信号处理学渣5 小时前
matlab画图,选择性显示legend标签
开发语言·matlab
红龙创客5 小时前
某狐畅游24校招-C++开发岗笔试(单选题)
开发语言·c++
Lenyiin5 小时前
第146场双周赛:统计符合条件长度为3的子数组数目、统计异或值为给定值的路径数目、判断网格图能否被切割成块、唯一中间众数子序列 Ⅰ
c++·算法·leetcode·周赛·lenyiin