C++ 通过指针实现多态实例详解

C++ 通过指针实现多态实例详解

多态是面向对象编程语言的一个重要特性。在 C++ 中,实现多态的方法有虚函数和虚函数表、函数指针和指针数组、以及指针和引用等。其中,通过指针实现多态是一种常用的方式。在本篇文章中,我们将详细讲解如何通过指针实现多态。

什么是多态

多态是指不同的对象以不同的方式响应相同的消息的能力,这意味着不同的对象可以接受相同的消息,但是却可以表现出不同的行为。例如,在一个图形类中,不同的子类可以有不同的绘制方法,但是它们都可以接收“绘制”这个消息。

如何通过指针实现多态

在 C++ 中,通过指针实现多态的方法是将子类对象的指针赋值给父类对象的指针,并使用虚函数来调用方法。因为虚函数可以通过指针调用子类的方法,所以这样可以保证正确地调用不同子类的方法。

以下是通过指针实现多态的详细步骤:

  1. 定义基类和子类的结构体,并在基类中定义虚函数。
class Shape {
public:
    virtual void draw() { // 定义虚函数,使用 virtual 关键字
        std::cout << "This is a shape." << std::endl;
    }
};

class Circle : public Shape {
public:
    void draw() { // 重写虚函数
        std::cout << "This is a circle." << std::endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() { // 重写虚函数
        std::cout << "This is a rectangle." << std::endl;
    }
};
  1. 在 main 函数中使用基类指针指向不同的子类对象。
int main() {
    Shape* shapes[2]; // 定义基类指针的数组
    Circle circle;
    Rectangle rectangle;
    shapes[0] = &circle; // 将子类对象的指针赋值给父类对象的指针
    shapes[1] = &rectangle;
    for (int i = 0; i < 2; ++i) {
        shapes[i]->draw(); // 调用虚函数
    }
    return 0;
}
  1. 编译运行程序,输出结果为:
This is a circle.
This is a rectangle.

这说明成功地实现了通过指针实现多态。

示例说明

示例 1

在这个示例中,我们通过指针实现了动物类和其两个子类,马和狗。每个子类都有一个不同的叫声函数。我们通过指针数组,将不同的子类对象指针赋值给基类对象指针,然后调用虚函数,从而实现了多态。

#include <iostream>

class Animal {
public:
    virtual void makeSound() { // 定义虚函数
        std::cout << "This is an animal." << std::endl;
    }
};

class Horse : public Animal {
public:
    void makeSound() { // 重写虚函数
        std::cout << "This is a horse. Neigh!" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() { // 重写虚函数
        std::cout << "This is a dog. Woof!" << std::endl;
    }
};

int main() {
    Animal* animals[2]; // 定义基类指针的数组
    Horse horse;
    Dog dog;
    animals[0] = &horse; // 将子类对象的指针赋值给父类对象的指针
    animals[1] = &dog;
    for (int i = 0; i < 2; ++i) {
        animals[i]->makeSound(); // 调用虚函数
    }
    return 0;
}

运行程序,输出结果为:

This is a horse. Neigh!
This is a dog. Woof!

示例 2

在这个示例中,我们通过指针实现了图形类和其两个子类,圆形和矩形。每个子类都有一个不同的绘制函数。我们通过指针数组,将不同的子类对象指针赋值给基类对象指针,然后调用虚函数,从而实现了多态。

#include <iostream>

class Shape {
public:
    virtual void draw() { // 定义虚函数
        std::cout << "This is a shape." << std::endl;
    }
};

class Circle : public Shape {
public:
    void draw() { // 重写虚函数
        std::cout << "This is a circle." << std::endl;
    }
};

class Rectangle : public Shape {
public:
    void draw() { // 重写虚函数
        std::cout << "This is a rectangle." << std::endl;
    }
};

int main() {
    Shape* shapes[2]; // 定义基类指针的数组
    Circle circle;
    Rectangle rectangle;
    shapes[0] = &circle; // 将子类对象的指针赋值给父类对象的指针
    shapes[1] = &rectangle;
    for (int i = 0; i < 2; ++i) {
        shapes[i]->draw(); // 调用虚函数
    }
    return 0;
}

运行程序,输出结果为:

This is a circle.
This is a rectangle.

结论

通过指针实现多态是 C++ 中一种常用的实现多态的方式。它让不同的子类对象以不同的方式响应相同的消息,从而实现了多态。在使用中要注意虚函数的定义和指针的使用,才能保证程序的正确性和可读性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C++ 通过指针实现多态实例详解 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • oracle序列(查询序列的值 修改序列的值)

    以下是“Oracle序列(查询序列的值 修改序列的值)”的完整攻略,过程中包含两个示例说明的标准格式文本: Oracle序列(查询序列的值 修改序列的值) 在Oracle数据库中,序列是一种用于生成唯一数字的对象。序列可以用于生成主键、唯一标识符等。本文将介绍如何查询序列的值和修改序列的值。 1. 序列的值 查询序列的值可以使用SELECT语句和NEXTVA…

    other 2023年5月10日
    00
  • springboot自定义yml配置文件及其外部部署过程

    首先,我们需要了解什么是YAML配置文件。YAML 是一种可读性高,用来表达数据序列化的格式。YAML 的定位是方便人类阅读的配置文件,对于机器来说,它也很容易解析。因此,SpringBoot 采用了 YAML 作为自己的配置文件格式。 下面是关于如何自定义 SpringBoot 的 YAML 配置文件及外部部署的完整攻略: 1. 在代码中加入自定义的 YA…

    other 2023年6月25日
    00
  • 基于CentOS搭建基于 ZIPKIN 的数据追踪系统

    基于CentOS搭建基于 ZIPKIN 的数据追踪系统 在分布式系统中,数据追踪是非常重要的一环。因为分布式系统的运行环境往往比较复杂,所以对于问题的排查和分析也比较有挑战性。常常我们需要监控分布式系统中的各个节点之间的交互,并可视化分析这些数据,这就需要用到一种叫做数据追踪的技术。 在本例中,我们将演示如何基于CentOS操作系统搭建数据追踪系统,使用Zi…

    其他 2023年3月28日
    00
  • jquery页面刷新(局部、全部)问题分析

    jQuery页面刷新(局部、全部)问题分析 jQuery是一种流行的JavaScript库,用于在客户端开发中提供高级的交互效果、动态、渐进增强效果等等。在网站开发中,我们可能会遇到需要实现页面的刷新,包括局部和全部的刷新。这篇文章将分析使用jQuery实现页面刷新的方法。 页面刷新 在使用jQuery进行页面刷新之前,我们需要了解何时需要对页面进行刷新。有…

    其他 2023年3月28日
    00
  • Mybatis加载策略的实现方法

    针对Mybatis加载策略的实现方法,我们可以从以下几个方面进行分析和解释。 1. Mybatis加载策略的概念 Mybatis加载策略是指Mybatis在进行数据查询时,如何加载对象的关联数据的一种策略和机制。具体地,Mybatis加载策略分为两种: 延迟加载(Lazy Loading):在实际使用到关联数据时,才从数据库中加载对应的数据。 即时加载(Ea…

    other 2023年6月25日
    00
  • dockertoolbox家庭版

    dockertoolbox家庭版 随着Docker在开发者社区不断升温,我们的生活也因为Docker而更加简单,因为Docker可以提供强大的容器化能力,使得我们的软件开发和部署变得很容易。但是,如果你是使用Windows系统的用户,你就需要安装一个Docker工具箱才能使用Docker。那么,dockertoolbox家庭版是一个好的选择。 什么是dock…

    其他 2023年3月28日
    00
  • vue动态路由实现多级嵌套面包屑的思路与方法

    Vue动态路由实现多级嵌套面包屑的思路与方法 在Vue中,我们可以通过动态路由来实现多级嵌套面包屑导航。下面是一个完整的攻略,包含了思路和方法,并提供了两个示例说明。 思路 实现多级嵌套面包屑导航的思路如下: 在路由配置中定义每个路由的meta字段,用于存储面包屑导航的信息。 在组件中使用$route对象获取当前路由信息,并根据meta字段生成面包屑导航数据…

    other 2023年7月27日
    00
  • Xmind8 Pro 最新激活序列号

    Xmind8 Pro 最新激活序列号攻略 1. 确认Xmind8 Pro版本 在进行激活序列号之前,首先需要确认当前安装的Xmind8 Pro版本。可以在软件界面的左上角找到“Xmind8”菜单,点击下拉菜单中的“关于Xmind8”,弹出的窗口中会显示当前版本信息。请确保下载的序列号与当前版本匹配。 示例说明:如果当前安装的Xmind8版本为3.7.6,则需…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部