重载和覆盖

简介: 重载(overloding)和覆盖(overriding)这两个词语对于学习OO开发的人应该不会陌生,也不应该陌生,相反的而应该将这两个的区别弄的一清二楚,话说,其实当年在学习的时候对这两个的的更深入的内容不是很清楚。

重载(overloding)和覆盖(overriding)这两个词语对于学习OO开发的人应该不会陌生,也不应该陌生,相反的而应该将这两个的区别弄的一清二楚,话说,其实当年在学习的时候对这两个的的更深入的内容不是很清楚。

重载是出现在同一个类中的就是函数名一样,而参数个数和类型不一样的,而覆盖是出出现在子类中的,子类用来覆盖父类中的同名函数,这几句话是老师苦口婆心交给我们的,而则两句似乎也成了口头禅。

多年以后,仔细品味身边的书籍,有一种突如其来的想法,想自己写一写东西,还是看下面的一个例子:

#include <stdio.h> 
#include <iostream> 
  
/**  
*Shape 
*/
class CShape 
{ 
public: 
CShape(){} 
virtual ~CShape(){} 
  
virtual void Draw()

{

printf("Hello! I am Base!/n");


}

}; /** *Point */ class CPoint : public CShape { public: CPoint(){} ~CPoint(){} void Draw() { printf("Hello! I am Point!/n"); } }; /** *Line */ class CLine : public CShape { public: CLine(){} ~CLine(){} void Draw() { printf("Hello! I am Line!/n"); } }; void main() { CShape* shape = new CPoint(); //draw point shape->Draw();//在这里shape将会调用CPoint的Draw()函数 delete shape; shape = new CLine(); //draw Line shape->Draw();//而在这里shape将会调用CLIne 的Draw()函数 delete shape; return ; }

同一个父类调用同一个方法,结果却是不一样,当然这是我们想要的结果,这种在OOP叫做多态,OO的三大特性之一就有多态这个说法。
多态:字面的含义是具有多种形式或形态。C++多态有两种形式,动态多态和静态多态;动态多态是指一般的多态,是通过类继承和虚函数机制实现的多态;静态多态是通过模板来实现,因为这种多态实在编译时而非运行时,所以称为静态多态。

动态多态是我们常用的,其是在运行阶段进行时确定函数的调用,在C++中要达到这个效果,就要使用虚函数,有一个词语,叫迟后绑定或者运行时绑定或者晚绑定,说的就是这个;静态多态是在编译阶段将函数的调用关系就确定了,因此也叫早绑定。

其实这两个过程也就是高级语言的两个过程,编译和运行,至于这两个过程分别做些什么处理,计算机的书籍上都有很详细的介绍,我也就不罗嗦了。

在C++中实现这种动态多态常见的用法就是声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。

如果不用虚函数,实际会是什么样子呢?

 

#include <stdio.h> 
#include <iostream> 
  
/**  
*Shape 
*/
class CShape 
{ 
public: 
CShape(){} 
virtual ~CShape(){} 
  
 void Draw()

{
printf("Hello! I am Base!/n");

} }; /** *Point */ class CPoint : public CShape { public: CPoint(){} ~CPoint(){} void Draw() { printf("Hello! I am Point!/n"); } }; /** *Line */ class CLine : public CShape { public: CLine(){} ~CLine(){} void Draw() { printf("Hello! I am Line!/n"); } }; void main() { CShape* shape = new CPoint(); //draw point shape->Draw();//调用CShape的Draw()函数 delete shape; shape = new CLine(); //draw Line shape->Draw();//调用CShape的Draw()函数 delete shape; return ; }

 

如果没有使用虚函数的话,即没有利用C++多态性,则利用基类指针调用相应的函数的时候,将总被限制在基类函数本身,而无法调用到子类中被重写过的函数。

 

 

下面这个例子就是静态多态,在编译阶段就知道要调用的函数:

 

 

template <class T> 
void DrawShape(T* t) 
{ 
t->Draw(); 
} 
  
修改main函数为如下: 
  
void main() 
{ 
CShape* shape = new CPoint(); 
//draw point 
shape->Draw(); 
  
DrawShape<CPoint>((CPoint*)shape); 
delete shape; 
  
shape = new CLine(); 
//draw Line 
shape->Draw(); 
DrawShape<CLine>((CLine*)shape); 
delete shape; 
  
  
return ; 
}

 

对于Java的程序员,也可以实现多态,但是只要子类继承了父类,并且在子类中重写了父类中的同名方法,那么将子类作为父类的变量值的时候,运行的时候会调用子类的方法而不是父类的,为什么会出现这种情况?如果按照C++的这种写法,那么只要不是虚函数,就调用的一定是父类的,答案在于Java中的函数都是虚函数。

 

 

相关文章
|
5天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
15天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
9天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
590 212
|
4天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
234 138
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
828 60
|
7天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1217 157
|
6天前
|
存储 安全 固态存储
四款WIN PE工具,都可以实现U盘安装教程
Windows PE是基于NT内核的轻量系统,用于系统安装、分区管理及故障修复。本文推荐多款PE制作工具,支持U盘启动,兼容UEFI/Legacy模式,具备备份还原、驱动识别等功能,操作简便,适合新旧电脑维护使用。
514 109