首页 > 编程语言 >(新!)c++多态

(新!)c++多态

时间:2024-10-19 19:46:13浏览次数:3  
标签:函数 area int 多态 c++ Shape 基类

C++ 多态

多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。

C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。

下面的实例中,基类 Shape 被派生为两个类,如下所示:

实例

#include <iostream> using namespace std; class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } int area() { cout << "Parent class area :" <<endl; return 0; } }; class Rectangle: public Shape{ public: Rectangle( int a=0, int b=0):Shape(a, b) { } int area () { cout << "Rectangle class area :" <<endl; return (width * height); } }; class Triangle: public Shape{ public: Triangle( int a=0, int b=0):Shape(a, b) { } int area () { cout << "Triangle class area :" <<endl; return (width * height / 2); } }; // 程序的主函数 int main( ) { Shape *shape; Rectangle rec(10,7); Triangle tri(10,5); // 存储矩形的地址 shape = &rec; // 调用矩形的求面积函数 area shape->area(); // 存储三角形的地址 shape = &tri; // 调用三角形的求面积函数 area shape->area(); return 0; }

当上面的代码被编译和执行时,它会产生下列结果:

Parent class area :
Parent class area :

导致错误输出的原因是,调用函数 area() 被编译器设置为基类中的版本,这就是所谓的静态多态,或静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定,因为 area() 函数在程序编译期间就已经设置好了。

但现在,让我们对程序稍作修改,在 Shape 类中,area() 的声明前放置关键字 virtual,如下所示:

class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } virtual int area() { cout << "Parent class area :" <<endl; return 0; } };

修改后,当编译和执行前面的实例代码时,它会产生以下结果:

Rectangle class area :
Triangle class area :

此时,编译器看的是指针的内容,而不是它的类型。因此,由于 tri 和 rec 类的对象的地址存储在 *shape 中,所以会调用各自的 area() 函数。

正如您所看到的,每个子类都有一个函数 area() 的独立实现。这就是多态的一般使用方式。有了多态,您可以有多个不同的类,都带有同一个名称但具有不同实现的函数,函数的参数甚至可以是相同的。

虚函数

虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。

我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定

纯虚函数

您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。

我们可以把基类中的虚函数 area() 改写如下:

class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } // pure virtual function virtual int area() = 0; };

= 0 告诉编译器,函数没有主体,上面的虚函数是纯虚函数

标签:函数,area,int,多态,c++,Shape,基类
From: https://blog.csdn.net/Programmersa/article/details/143083188

相关文章

  • 洛谷知识点——C++ 11 实现一次性输出多行文本
    完整语法是R"deli(...)deli"。(其中deli并不是固定的,那里其实是一个用户自定义的字符序列,最多16个基本字符,不可含反斜线,空格和小括号。)故P1000超级玛丽游戏解法为#include<iostream>usingnamespacestd;intmain(){cout<<R"(********......
  • C++基础
    1、注释单行注释://这是注释多行注释:/*这是注释*/2、变量 数据类型变量名=变量初始值; 3、常量宏常量:通常在文件开头定义#define常量名常量值const修饰的静态变量,表示一个常量,不可修改。const数据类型常量名=常量值#include<iostream>usingna......
  • 「图::连通」详解并查集并实现对应的功能 / 手撕数据结构(C++)
    目录概述成员变量创建销毁根节点访问路径压缩启发式合并复杂度Code概述并查集,故名思议,能合并、能查询的集合,在图的连通性问题和许多算法优化上着广泛的使用。这是一个什么数据结构呢?一般来讲,并查集是由一系列集合组成的集合群。其中,每个集合都有一个根节点,它的......
  • 学习记录,这该死的c++
    最近还是比较懈怠,除了老师布置的作业其他的也是匆匆过一眼至于代码方面最主要的问题还是不理解该怎么表达。总的来说还是要在多沉淀。为什么会有知道敲代码但是不知道该怎么成功表达这个问题啊?还是不能把代码敲得精简一些可以来个人教我怎么敲关系符号吗?运用的还不是很熟练......
  • 【C++贪心】2086. 喂食仓鼠的最小食物桶数|1622
    本文涉及知识点C++贪心LeetCode2086.喂食仓鼠的最小食物桶数给你一个下标从0开始的字符串hamsters,其中hamsters[i]要么是:‘H’表示有一个仓鼠在下标i,或者’.’表示下标i是空的。你将要在空的位置上添加一定数量的食物桶来喂养仓鼠。如果仓鼠的左边或右边......
  • 南沙C++信奥赛陈老师解一本通题 1286:怪盗基德的滑翔翼
    ​【题目描述】怪盗基德是一个充满传奇色彩的怪盗,专门以珠宝为目标的超级盗窃犯。而他最为突出的地方,就是他每次都能逃脱中村警部的重重围堵,而这也很大程度上是多亏了他随身携带的便于操作的滑翔翼。有一天,怪盗基德像往常一样偷走了一颗珍贵的钻石,不料却被柯南小朋友识破了伪......
  • C++之子类继承与父类构造
    C++之子类继承与父类构造文章目录C++之子类继承与父类构造1.问题引出2.原则3.解析3.1单一继承3.1.1父类无参构造函数3.1.1.1子类无定义构造函数3.1.1.2子类定义构造函数3.1.2父类存在无参构造函数和有参构造函数3.1.3父类仅存在有参构造函数3.2链式继承3.3多继承......
  • 【C++】C++中的继承,看这一篇就够了
    【C++】C++中的继承,看这一篇就够了一.继承的概念及定义继承的概念继承定义继承关系和访问限定符继承基类成员访问方式的变化二.基类和派生类对象赋值转换三.继承中的作用域四.派生类的默认成员函数五.继承与友元六.继承与静态成员七.复杂的菱形继承及菱形虚拟继承......
  • 移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——13.map&&set(无习题)
    C++中的set和map容器详细总结1.概述C++标准模板库(STL)提供了多种关联容器,用于管理键值对和集合的数据。其中,set和map是最常用的两种关联容器。set用于存储唯一的元素集合,而map则用于存储键值对,其中每个键都是唯一的。它们都使用红黑树(自平衡二叉搜索树)作为底......
  • YU_C++算法学习笔记 · 枚举
    1.1枚举类问题·枚举是什么?枚举也叫穷举,是计算机解决问题最基本的策略。其方法是一一列举所有的可能性,根据题意要求进行合理的判断或计算,最终得到答案,本质上就是一种搜索算法基础的枚举就是人们常说的“暴力”求解。对于不同的问题,不可过分依赖“暴力”求解,应该根据具体的......