C++---多态与虚函数

多态性

  • 多态是面向对象编程的一个重要特性, 同一个实体, 多种形态.
  • 面向对象编程的多态性包含
    • 向不同的对象发送同一条消息, 不同的对象在接收时不会产生不同的行为, 即不同的实现, 调用不同的函数, 函数名相同, 但是执行的具体细节不同

静态多态性

  • 静态多态, 也称为编译时多态, 使用函数重载的方式

  • 函数重载有以下特点:

    • 函数名相同
    • 函数参数个数不同
    • 如果函数个数相同, 参数类型不相同
    • 如果函数个数 类型都形同, 那么顺序不同
    • 函数重载与函数返回值无关
class GameCore{
public:
void MoveRole(Warrior& warrior);
void MoveRole(Archmage& archmage);
void MoveRole(Assassin& assa);
}

void GameCore::MoveRole(Warrior& warrior)
{
warrior.Move();
}

void GameCore::MoveRole(Archmage& archmage)
{
archmage.Move();
}

void GameCore::MoveRole(Assassin& assa)
{
assa.Move();
}

动态多态性

  • 动态多态, 使用的函数重写的方式.
  • 要实现C++函数重写, 必须要先把父类的成员函数设定为虚函数
  • 派生类重写基类方法时可以加上override关键字, 表示重写
  • override关键字为C++11标准以后新加入的, 用来明确派生类重写基类继承来的虚函数
//virtual 返回值  函数名();

class Hero
{
    public:	
    	//设定为虚函数
    	virtual void Move();
}


class Warrior: public Hero
{
    public:
    	//派生类重写
    	void Move() override;
}

向上和向下转换

  • 当B时A的子类型时(class B :public A),意味着所有对A对象的操作都可以对B对象进行, 即B重用A的操作来实现自己的操作。

  • 向上转换:把子类型对象转换为父类型对象

    • 向上转换是安全的
    • 向上转换可以自动完成,即自动类型转换
    • 向上转换的过程中,会丢失子类型信息,再调用子类的方法时编译器会报错
    • 如果还想使用子类方法,就需要再进行强制转换---向下转换
  • 向下转换:把父类型对象转为子类型对象

    • 向下转换不安全, 因为要转换的父类对象有可能是父类型的另一个子类型

      //Warrior和Archmage都是Hero的子类
      
      Archmage warrior;
      Hero& hero = warrior;
      Warrior& newWarrior = (Warrior&)hero;
      

纯虚继承与抽象类

虚函数

image-20200507165252466

image-20200509143824934

  • 注意
    • 构造函数不能是虚函数
    • 析构函数应该是虚函数,通常基类提供一个虚析构函数,即使它不需要析构函数
      • 如果基类析构函数不加virtual关键字,那么派生类对象在释放时,只会调用基类的析构;加上virtual关键字后,会先调用派生类的析构函数,再调用基类的析构函数
    • 友元函数不能是虚函数, 因为友元不是类的成员

纯虚函数与抽象类

纯虚函数

  • virtual 返回类型 函数名(参数列表) const = 0; 这样的虚函数就叫做纯虚函数
  • 纯虚函数没有函数体,只有函数名, 不能在基类中被调用
  • 纯虚函数要求必须由派生类来实现纯虚函数体的功能

抽象类

  • 如果声明的类,所有的成员函数都是纯虚函数,那么该类叫做抽象类
  • 抽象类用来定义业务接口,即没有实现
  • 抽象类不能用来创建一个对象, 即不能实例化
  • 暂时无法实现的函数,可以声明为纯虚函数,留给派生类去实现
  • 设计类时,如果需要在派生类中重新定义基类方法,那么就将这个方法设置为虚方法。
原文地址:https://www.cnblogs.com/KX-Lau/p/12857635.html