C++ 和 Delphi 的函数覆盖(Override)与重载(overload)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

C++ 和 Delphi 的函数覆盖(Override)与重载(overload)

Spacesoft【暗夜狂沙】

在面向对象编程中,当子类继承了来自基类的函数后,子类有可能需要对其中的一些函数作出与基类不同处理,比如:

class CHuman
{
public:
    void SayMyName()//打印出对象的姓名
    {
        cout << "Hi, I am a human" << endl;
    } 
};

那么很明显,假如他的子类有一个同名、同参数和返回值(一句话,一摸一样)的函数SayMyName,它会调用哪个函数呢?比如现在有一个class CMark

class CMark: public CHuman
{
public:
    void SayMyName()
    {
        cout << "Hi, I am mark" << endl;
    }
};

那么我们要问,下面的程序段:

CHuman *pH = new CMark;
 
if (pH)
    pH->SayMyName();
else
    cout << "cast error! " << endl;

delete pH;
pH = NULL;

要打印出来的,真的是我们想要的Hi, I am mark 吗?

不是。它输出了Hi, I am a human。这很糟糕,当我们指着一个人要他说出自己的名字的时候,他却告诉我们他“是一个人”,而不是说出自己的名字。出现这样的问题原因在于,用基类的指针指向公有派生类,可以访问派生类从基类中继承的成员函数。但如果派生类中也有同名的函数,则结果仍然是访问基类的同名函数,而不是派生类本身的函数。而事实上,我们希望的是由一个对象的真实类型来决定到底该调用这些同名函数中的哪一个,就是说,这样的决议是动态(Dynamic)的。或者我们可以说,我们希望当一个对象是子类型时,它的同名函数在子类中的实现覆盖(override)掉基类的实现。

我们先从C++对这个问题的处理说起。

这是C++中比较典型的多态的例子,C++用虚函数来实现这样的多态。具体点说,就是使用virtual 关键字来将函数说明成虚函数,在上一个例子中就是应该声明成:

class CHuman
{
public:
    virtual void SayMyName()//打印出对象的姓名
    {
        cout << "Hi, I am a human" << endl;
    } 
};

这样,其他的代码还是那个老样子,但是我们的CMark 已经知道怎么说自己的名字了。CMark 的SayMyName()函数是否加了virtual 关键字的说明并没有关系,因为根据C++语法的规定,因为它覆盖了CHuman 的同名函数,它自己也就成为virtual 的了。至于为什么一个virtual 关键字有那么神奇的效果呢?C++ FAQ Lite 对此是这样说明的: 在C++中,“虚成员函数是动态确定的(在运行时)。也就是说,成员函数(在运行时)被动态地选择,该选择基于对象的类型,而不是指向该对象的指针/引用的类型”。于是我们的pH就发现自己其实指向的是一个CMark类型的对象,而不是自己的类型所声明的CHuman,所以它聪明的调用了CMark的SayMyName。


而Delphi 就是用override 关键字来说明函数覆盖的。被覆盖的函数必须是虚(virtual)的,或者是动态(dynamic)的,也就是说该函数在声明时应该包含这两个指示字中的一个,比如:

procedure Draw; virtual;

在需要覆盖的时候,只需要在子类中用override 指示字重新声明一下就可以了。

procedure Draw; override;

在语法上来说,声明为 virtual和 dynamic是等价的。它们的差别在于,前者在实现上对速度进行了优化,而后者对代码大小进行了优化。

假如基类和子类都含有同一个函数名和参数,并且在子类中不加override 指示字呢?这在语法上也是正确的。这意味着子类的函数同名实现把基类的实现隐藏(hide)掉了,尽管这二者在派生类中都存在。那么就回到了本文开头的第一个例子说明的情况:当我们指着一个人要他说出自己的名字的时候,他却告诉我们他“是一个人”,而不是说出自己的名字。

值得注意的是,与我们在C++ 中常常不加区分的把覆盖一个函数和重载一个函数通称为重载不同,在Delphi 中,只有重载(overload) 才是我们平时所说的重载,被重载的函数依然存在,依靠参数来决定到底调用那个实现。当然,当overload掉的函数和基类的函数参数相同时,基类的实现就被hide掉了,就像上面提到的一样。而覆盖(override)则是把让被覆盖的函数不可见了,确确实实的"覆盖"掉了,原来的实现就不见了。基于这样的原因,许多文章甚至一些书都错误的把override翻译成重载,笔者认为并不合适。 

C++头文件转Delphi工具:原理、实现跨语言接口实践 在Windows桌面开发领域,跨语言调用是常见的工程需求,尤其是C++Delphi之间的互操作。其核心原理在于理解两种语言在数据类型、内存布局函数调用约定上的差异,并建立准确的映射关系。这涉及到对应用程序二进制接口(ABI)的深入掌握,包括结构体对齐、指针传递名称修饰等底层细节。从技术价值看,可靠的自动转换工具能极大提升开发效率,减少手动绑定易引入的错误,保障项目的稳定性可维护性。典型的应用场景包括集成硬件厂商的C++ SDK、调用高性能算法库,或在遗留系统中复用Delphi的界面框架。本文通过解析 阅读详情

相关推荐

Delphi 基础知识 12】覆盖函数的使用

GUI开发: 在图形用户界面 (GUI) 应用程序中,你可能会定义一个基础的控件类,例如 TControl,并在派生类中覆盖或扩展一些方法,以适应不同的控件类型(按钮、文本框等)。框架类库设计: 在设计类库或框架时,父类可能包含一些通用的方法,而子类可以通过覆盖这些方法来实现特定的行为,使得框架更加灵活可扩展。数据库访问: 在数据库访问框架中,基类可以提供通用的数据库操作方法,而不同的数据库引擎可以通过覆盖这些方法来提供特定引擎的实现。基类可以定义插件接口,而插件通过覆盖这些接口方法来提供具体的实现。

记录日常技术经验 716

delphioverride overload

delphioverride overload override 参数返回值要父类相同 overload 参数或返回值父类不同 若参数有默认值, 例如:function GetIndexFileName: string; function GetIndexFileName(aIndexType:string = 'OFI'): string; 则调用时GetIndexFileName 会不清楚调用哪个函数 ...

weixin_46639851的博客 678

Delphi中用友华表Cell函数的高级自定义技巧

UFTable控件是用友华表控件中的核心组件之一,其主要功能是提供一个类似于数据库表的可视化界面。它允许开发者在Delphi应用程序中轻松地实现复杂的表格数据处理展示。控件的基本功能包括但不限于:单元格数据的展示编辑列的自定义排序筛选数据行的新增、删除编辑数据的导入导出操作这些功能为开发者提供了丰富的表格操作接口,大大简化了表格数据处理的复杂性。通过UFTable控件,开发者能够快速地构建出既美观又功能强大的数据管理界面。

weixin_36299472的博客 1099

delphi-多态(overload,override)接口(interface)

delphi-多态(overload,override)接口(interface) 先来聊聊重载问题(也叫超载,总之是那个Overload)吧。在同一个类中,出现多个同名的方法的现象就是Overload。联系起上面提到的兄弟俩,我想这更好理解。他们从外观上是相似的,不同的是某些“参数”,类型上可能各异或是个数上不同。 在Delphi中,所有方法都默认是静态的,便于编译器链...

551

Delphi重载覆盖,多态

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34393428的博客 416

C++ Delphi函数覆盖(Override)重载(overload

C++ Delphi函数覆盖(Override)重载(overload) Spacesoft【暗夜狂沙】 在面向对象编程中,当子类继承了来自基类的函数后,子类有可能需要对其中的一些函数作出基类不同处理,比如: class CHuman { public: void SayMyName()//打印出对象的姓名 { cout } }; 那么

技术收藏 938

谈谈重载overload覆盖override隐藏

这三个概念都是OO中的多态有关系的。如果单是区别重载覆盖这两个概念是比较容易的,但是隐藏这一概念却使问题变得有点复杂了,下面说说它们的区别吧。 重载是指不同的函数使用相同的函数名,但是函数的参数个数或类型不同。调用的时候根据函数的参数来区别不同的函数覆盖(也叫重写)是指在派生类中重新对基类中的虚函数(注意是虚函数)重新实现。即函数参数都一样,只是函数的实现体不一样。隐藏是指派

裸奔人生 745

重载(overload)覆盖(override)隐藏

重载overload)用于同一个类中的成员函数,其特征为:(1)相同的范围(在同一个类中);(2)相同的函数名字;(3)参数不同(包括参数类型不同,或参数个数不同,或两者都不同。注意:返回值没关系);(4)是否为虚函数无关。覆盖override)是指派生类函数覆盖基类函数,其特征为:(1)不同的范围(分别位于派生类基类);(2)相同的函数名字;(3)参数相同(即参数类型参数个数均相同)...

web开发自学 121

reintroduceoverride overload有何区别,怎么使用?

reintroduceoverride overload有何区别,怎么使用?     在子孙类中要声明一个祖先类中参数不同的方法的时候用Reintroduce,     但需要重新定义一个祖先类总的虚拟的或者动态的方法的时候,要用到Override;如果祖先类中的方法不是虚拟的或者动态的(定义的时候有virtual;就是虚拟的,有dynamic;就是动态的);那么是没有办法override的     至于Overload,一般适用于定义一组不同参数的函数,这些函数也可以不是Of Objects(中文该怎

娃娃鸭的专栏 4696

重载覆盖

override   函数参数类型以及返回类型必须相同,即签名都是一致的——或者叫相貌衣服都是一样的,一般用在继承过程中。(高手判断一下,除了实现细节,其他的是不是什么都应该相同?所以叫做“重写”——《C++编程思想》上是这么翻译的。) overload   函数名必须相同,签名必须不同(参数个数,顺序,类型),返回类型可以不同,用在同一个类中,在编译时候确定。

小虾米就是我喽 417

DELPHIVC口水战”之补白

这里是原文:http://blog.csdn.net/jiangtao/archive/2001/03/05/1821.aspx  原文写得不错,不但引经据典,还罗列了十几条大多有统计数据的比较,不过,严格地说,DELPHI是一个IDE,它并不代表PASCAL这门语言,而VC也只是一个IDE,它并不代表C++,而MFC也不是它的全部,那么,把DELPHIVC相比,到底是比什么呢?  如果是比“用

于无声处 3343

171230—重载覆盖、隐藏

按:一入此门深似海…… 此篇仅是个人的一些理解。希望能把自己之前遇到的问题的思考后续研究整理出来。 此诸概念在面向对象的编程范围内讨论。重载:(overloaded)抄百度:重载,简单说,就是函数或者方法有相同的名称,但是参数列表不相同的情形,这样的同名不同参数的函数或者方法之间,互相称之为重载函数或者方法。也就是说,重载,是在同一个类中,多个函数共用一个函数名,但由于其参数的不同,各函数可以

DRondong的博客 327

浅析重载、隐藏覆盖

重载 重载又称为静态多态,静态绑定,静态决议等。因为要实现重载,所以C++C的命名方式有所不同。重载主要是为了减轻程序员对函数名的记忆负担,让所有功能相似的函数使用同一名字。 重载条件: (1)在同一作用域中 (2)函数名相同 (3)参数列表不同 隐藏 隐藏是因为在子类中定义了基类同名的函数

double_happiness的博客 827

delphi C++的基本语法区别

http://www.cnblogs.com/Braveliu/p/3602784.html 【1】“=”符号 (1)“=”作为比较符。但是,当定义const常量时,“=”又表示赋值符号。而“:=”作为赋值符号。 (2)“=”只表示赋值符号 【2】结构体 (1)record 作为结构体 (2)struct 作为结构体 【3】继承 (1)

ly930156123的博客 1084

Delphi语言的VCL框架

因此,main 函数的作用是初始化应用程序,并启动消息循环,而 TApplication 组件负责处理消息循环并转发消息。除了 TApplication TWinControl 组件外,VCL 还提供了一些其他的组件来处理特定类型的消息,如 TTimer 组件用于处理定时器消息,TMessage 组件用于处理自定义消息等等。在 Delphi 应用程序中,TApplication 组件负责处理应用程序的消息循环,但它并不直接处理应用程序的 main 函数入口。

zhangzhechun的专栏 2261
上一篇: 浅谈delphi中的指针
下一篇: Delphi7在win2003Sp1下常见故障解决
iori13
博客等级 码龄20年 3粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值