首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在C中模拟OO风格的多态?

在C语言中,模拟面向对象风格的多态需要使用函数指针和结构体。以下是一个简单的示例,展示了如何在C语言中实现多态:

  1. 定义一个结构体,用于存储函数指针和其他数据。typedef struct Animal { void (*makeSound)(struct Animal*); // 其他数据成员 } Animal;
  2. 定义具体的动物类型,如狗和猫。typedef struct Dog { Animal base; // 其他数据成员 } Dog; typedef struct Cat { Animal base; // 其他数据成员 } Cat;
  3. 为具体的动物类型实现makeSound方法。void dogMakeSound(Animal* this) { printf("汪汪汪\n"); } void catMakeSound(Animal* this) { printf("喵喵喵\n"); }
  4. 初始化具体的动物实例,并设置函数指针。int main() { Dog dog; dog.base.makeSound = dogMakeSound; Cat cat; cat.base.makeSound = catMakeSound; // 使用多态调用makeSound方法 dog.base.makeSound(&dog.base); cat.base.makeSound(&cat.base); return 0; }

在这个示例中,我们使用了结构体和函数指针来模拟面向对象风格的多态。虽然C语言本身不支持面向对象编程,但通过这种方式,我们可以实现类似的功能。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++多态

那么在继承,需要以下条件才能构成多态: ①被调用函数必须是虚函数,且派生类必须对基类虚函数进行重写/覆盖。 ②必须通过基类指针或引用调用虚函数。...在上面的代码例子,只有派生类Student析构函数重写了Person析构函数,delete对象调用析构函数,才能构成多态,才能保证p1和p2指向对象正确调用析构函数。...C++11 override 和 final 到这里,我们可以看到构成多态条件比较严格,所有有时候我们会难免疏忽一下,可能是函数名字母次序写反而无法构成重载,而这种错误在编译期间是不会报出,只有在程序运行时没有得到预期结果才来...因此,C++11提供了overrid和final来帮助我们去检查是否构成重写。 final:修饰虚函数,表示该虚函数不能再被重写。...②动态绑定又称后期绑定(晚绑定),是在程序运行期间,根据具体拿到类型确定程序具体行为,调用具体函数,即上面所说,会先到虚表找具体函数地址,再去调用。动态绑定也称为动态多态

83320

C# 多态

相信大家都对面向对象三个特征封装、继承、多态很熟悉,每个人都能说上一两句,但是大多数都仅仅是知道这些是什么,不知道 CLR 内部是如何实现,所以本篇文章主要说说多态一些概念已经内部实现机理。...它特点是(三个相同): 相同方法名 相同参数列表 相同返回值 :父类定义: public virtual void EatFood() { Console.WriteLine("Animal...(); } 小提示:经常有童鞋问重载和重写区别,而且网络上把这两个区别作为 C# 做常考面试题之一。...: Animal a = new Animal(); a.EatFood(); 执行输出结果为: Animal吃东西 4、抽象方法:在基类定义并且必须在派生类重写方法,使用 abstract...下面我们就来深入一点,谈谈多态背后机理。 ---- 二、深入理解多态性 要深入理解多态性,就要先从值类型和引用类型说起。我们都知道值类型是保存在线程栈上,而引用类型是保存在托管堆

65220
  • c#多态学习总结

    c#多台方法,大体上和c++类似,但是有点区别的,我这里刚刚初学,因此把重点记录下。 多态是同一个行为具有多个不同表现形式或形态能力。 多态性意味着有多重形式。...在面向对象编程范式多态性往往表现为"一个接口,多个功能"。 多态性可以是静态或动态。在静态多态,函数响应是在编译时发生。在动态多态,函数响应是在运行时发生。...在C#,每个类型都是多态,因为包括用户定义类型在内所有类型都继承自Object。...多态就是同一个接口,使用不同实例而执行不同操作 1、静态多态性 在编译时,函数和对象连接机制被称为早期绑定,也被称为静态绑定。C#提供了两种技术来实现静态多态性。...c#,也有类似的特性,并且也更加多特性,有关抽象类一些规则: a、您不能创建一个抽象类实例。 b、您不能在一个抽象类外部声明一个抽象方法。

    81220

    你明白C++多态吗?(暑假提升-多态专题)

    在这篇文章已经讲过了C++一个重要特性-继承,想回顾一下可以点击一下链接,复习复习。...9、多态原理 9、1、虚函数表 就像是在继承虚继承一样,其中作为基类A在内存存放位置是在最底下,但是同样,为了保证是相同a,B和C在内存第一个地址位置存放着虚基表来帮助找到a位置...这篇文章还有图解释,这里就不再多赘述了。 **有趣是,多态原理和虚继承好像还有点相似,**其中多态,有着另一种表虚函数表。为了更能够理解虚函数表作用,我们先从一个题目来入手。...满足多态条件:那么这里调用生成指令,就会去指向对象虚表找对应函数进行调用。 不满足多态条件:直接就确定函数地址,而不去虚函数表里面找,因为直接找到了。 为什么重写也称为是覆盖呢?...9、2、多态原理 了解了虚函数表之后,想一想在第三个标题中图片内容,其实在底层实现也就是像这个样子。 **虚表:**虚函数表,存虚函数,目标实现多态

    8610

    C++四种多态

    本文转载自The Four Polymorphisms in C++ C++四种多态 当人们谈论C ++多态性时,通常是指通过基类指针或引用使用派生类事情,这称为子类型多态性。...但是他们经常忘记,C ++还有各种各样其他多态性,例如参数多态性,ad-hoc多态性和强制多态性。 这些多态性在C ++也有不同名称, - 子类型多态也称为运行时多态。...在本文中,我将通过C ++语言示例来说明所有多态性,并深入介绍为什么它们具有其他各种名称。 子类型多态性(运行时多态子类型多态是每个人在C ++说“多态”时所理解。...另一种解释方式是,编译器不在编译时定位要调用函数地址,而是在程序运行时通过在虚拟表取消引用右指针来调用该函数。 在类型理论,它也称为包含多态性。...参数多态性(编译时多态性) 参数多态性提供了一种对任何类型执行相同代码方法。 在C ++,参数多态性是通过模板实现

    1.3K20

    Objective-C继承和多态

    面向对象编程之所以成为主流编程思想和他继承和多态是分不开,只要是面向对象语言都支持继承和多态,当然不同OOP语言之间都有其特点。...在Objective-Csuper是指向直接父类指针,而self是指向本身指针,self就相当于javathis指针。...在Objectiv-C几乎所有的类都是继承自NSObject类,NSObject类存在大量功能强大方法。下面对NSObject类各种方法进行试验和介绍:         1....= str1"); }     ​    ​Objective-C继承         继承是is-a关系,比如猫咪是一个动物,那么动物是父类,而猫咪是动物子类。...2014-07-30 08:38:12.958 HelloOC[483:303] 我是富二代BILL`s son,我超喜欢飙车 ​Objective-C多态     ​    ​多态简单说就是对于不同对象响应同一个方法时做出不同反应

    1.2K80

    多态性 - C++实现运行时多态方式

    一、概述 C++多态性是指同一个函数可以有多种不同实现方式,并且在运行时根据实际情况进行选择执行。在C++实现多态有两种方式:静态多态和动态多态。...通过将函数声明为虚函数,我们可以在运行时根据对象实际类型来确定要调用函数实现。在C++,只要将函数声明为虚函数即可实现动态多态。...2、抽象类 抽象类是指包含至少一个纯虚函数类,这个类不能被实例化,只能用作基类来派生出其他类。在C++,可以通过将函数声明为纯虚函数来实现抽象类。...在调用函数`calculateArea`时,我们将基类指针指向派生类对象,可以看到运行时实际调用是派生类实现函数。 四、总结 本文介绍了C++实现运行时多态两种方式:静态多态和动态多态。...静态多态包括函数重载和模板函数,动态多态包括虚函数和抽象类。通过对这些知识点学习,可以更好地理解C++多态性,更灵活地应用在实际程序开发

    33210

    何在keras添加自己优化器(adam等)

    本文主要讨论windows下基于tensorflowkeras 1、找到tensorflow根目录 如果安装时使用anaconda且使用默认安装路径,则在 C:\ProgramData\Anaconda3...一般来说,完成tensorflow以及keras配置后即可在tensorflow目录下python目录中找到keras目录,以GPU为例keras在tensorflow下根目录为C:\ProgramData...找到optimizers.pyadam等优化器类并在后面添加自己优化器类 以本文来说,我在第718行添加如下代码 @tf_export('keras.optimizers.adamsss') class...# 传入优化器名称: 默认参数将被采用 model.compile(loss=’mean_squared_error’, optimizer=’sgd’) 以上这篇如何在keras添加自己优化器...(adam等)就是小编分享给大家全部内容了,希望能给大家一个参考。

    45K30

    C++】多态 ② ( 面向对象多态真正需求 | 面向对象 “ 多态 “ 实现 - virtual 修饰函数 | 代码示例 )

    一、多态实现 1、面向对象 " 多态 " 真正需求 在上一篇博客 【C++】多态 ① ( 类型兼容性原则与函数重写 | “ 多态 “ 引入 | 函数重写 ) , 进行了测试 , 在测试代码..., 这并不是我们想要 ; 上述测试 , 根据实际 对象类型 确定 重写函数 要调用 父类 还是 子类 函数 , 并不是我们期望 ; 多态 需求是 : 相同调用语句 , 有多种不通表现形态...指针 指向 父类 , 就调用父类函数 ; 指针 指向 子类 , 就调用 子类函数 ; 2、面向对象 " 多态 " 实现 - virtual 修饰函数 C++ 语言中 , 通过使用 virtual...关键字 , 实现对 多态支持 ; 子类 重写 父类 函数 , 在 父类 或 子类 , 使用 virtual 关键字 修饰 该函数 , 即可实现 多态 特性 ; 在 父类 , 使用 virtual..., 更容易理解 此处要开始使用 多态机制了 ; 二、代码示例 - 多态实现 1、代码示例 在下面的代码 , 使用 virtual 关键字 修饰 父类 和 子类 函数 , 最终实现了 多态 ; 代码示例

    13820

    C++虚函数多态实现原理刨析

    可写可不写,因为继承至Animal,因此国不写virtual,与父类里面speak同名函数也会默认为虚函数 virtual void speak() { cout << "小猫在说话" <<...区别: 代码本意是调用猫类里面的speak函数,但是未在父类speak函数前加virtual关键字时,调用是父类speak函数,加了virtual关键字后,调用是猫类里面的speak函数,这就是多态...在深入探究多态实现原理前,先要理解多态意思和虚函数实现条件 多态: 不同类对象对同一消息不同响应 注意: 虚函数实现条件 : 1.有继承关系 2.子类重写父类虚函数 动态多态使用...: 父类指针或者引用指向子类对象 多态实现原理探究: 未写虚函数前: #include using namespace std; class Animal { public:...当发生虚函数重写时,子类会把自己虚函数覆盖掉之前父类虚函数 因此当父类指针或者引用指向子类对象时候,会发生多态,你传入是cat对象,就去cat虚函数表找speak函数入口地址

    45010

    深入理解 C++ 多态与文件操作

    C++ 多态多态(Polymorphism)是面向对象编程(OOP)核心概念之一,它允许对象在相同操作下表现出不同行为。在 C++ 多态通常通过继承和虚函数来实现。...理解多态想象一个场景,你有一个动物园,里面有各种动物,猫、狗、鸟等。每个动物都有自己叫声。...然后,我们可以创建派生类, Cat、Dog 和 Bird,并重写它们 makeSound() 方法以实现各自叫声。...<< endl; }};在这个例子,Animal 类 makeSound() 函数被声明为虚函数,这意味着它可以在派生类中被重写。...可维护性: 多态可以提高代码可维护性,因为它使代码更易于理解和修改。多态实现在 C++ 多态实现主要依靠以下两个机制:继承: 如上所述,多态通常通过继承来实现。

    8910

    基于 FPGA 模拟C协议设计(

    大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣资源,或者一起煮酒言欢。 今天给大侠带来基于FPGA 模拟C 协议设计,由于篇幅较长,分三篇。...除此之外,由于 I²C 协议占用 IO 资源特别少,连接方便,所以工程也常选用 I²C 接口做为不同芯片间通信协议。...在现代电子系统,有为数众多 IC 需要进行相互之间以及与外界通信。...因此在 FPGA 模拟C 接口已成为 FPGA 开发必要步骤。...模拟C 协议设计(下),程序仿真与测试,包括主节点仿真、从节点仿真、仿真主程序、仿真结果以及总结等相关内容。

    47010

    何在canvas模拟css背景图片样式

    设置重复,但是canvas笔者只找到一个createPattern()方法,且只支持设置重复效果,那么如何在canvas里模拟一定css背景效果呢,不要走开,接下来一起来试试。...首先要说明是不会去完美完整100%模拟css所有效果,因为css太强大了,属性值组合很灵活,且种类非常多,其中单位就很多种,所有只会模拟一些常见情况,单位也只考虑px和%。...,高度没有设置,那么会根据图片长宽比自动缩放,效果如下: 在canvas模拟很简单,需要传给drawImage方法四个参数:img、x、y、width、height,img代表图片,x、y代表在画布上放置图片位置...width、height,也就是图片在canvas显示宽高,而在处理background-position时会用到图片宽高,但是我们传还是图片原始宽高,这样计算出来当然是有问题,修改一下:...imgHeight) { let y = oxRepeatY // ... } } } } 结尾 本文简单实现了一下在canvas模拟

    7.1K41

    何在模拟测试Windows Phone 8NFC应用

    众所周知Window Phone 8 SDK模拟器不支持NFC功能测试。...可喜是开源项目Proximity Tapper解决了在模拟测试NFC功能需求,可以实现Windows Phone 8 emulator模拟NFC操作,还可实现Windows Phone与Windows...由于Visual Studio不支持同时运行两个相同模拟器,你需要选择不同分辨率模拟器来解决此问题。模拟器启动后在Proximity TapperDevices中会发现此两个设备。...按住Ctrl键用鼠标选中两个模拟器,然后点击"Tap Selected Devices Remain Connected"。这样就可在两个模拟器之间测试NFC功能。...下图是笔者测试通过NFC功能发布应用Uri关联消息。第一台模拟器Publish Uri Message,第二台模拟器通过NFC接收到消息后可启动与此Uri关联应用。

    2.3K10

    基于FPGA模拟C协议系统设计(

    基于FPGA模拟C协议系统设计() 今天给大侠带来基于FPGA 模拟C 协议设计,由于篇幅较长,分三篇。今天带来第二篇,中篇,I²C 协议具体实现。话不多说,上货。...除此之外,由于 I²C 协议占用 IO 资源特别少,连接方便,所以工程也常选用 I²C 接口做为不同芯片间通信协议。...在现代电子系统,有为数众多 IC 需要进行相互之间以及与外界通信。...因此在 FPGA 模拟C 接口已成为 FPGA 开发必要步骤。...模拟C 协议设计(下),程序仿真与测试,包括主节点仿真、从节点仿真、仿真主程序、仿真结果以及总结等相关内容。

    98520

    C++模拟JAVA内部类方法

    有时候我们需要把一批互相关联API用不同类提供给用户,以便简化每个类使用难度。但是这样这些类之间数据共享就成了问题。...JAVA内部类可以自由访问外围类所有数据,所以很时候做这工作,而如果C++也这样做,就变成要增加很多setter和getter。...但是,也可以用以下方法模拟实现: 首先,你内部类头文件一般是被外围类所#include,所以需要在内部类声明前增加“前置声明”: namespace outerspace{ class OuterClass...以上是内部类设定,外部类就很简单,只需要保存内部类指针,然后设置好内部类为友元就可以了: friend InnerClass; private: InnerClass inner_obj; 外部类则需要在初始化过程设置...在设计API过程,内部类需要用到外部类任何成员,包括是private,都可以用 outer_obj->XXX直接引用。而外部类则可以直接返回内部类指针(引用)给使用者。

    2K40

    模拟实现C++string类(详细解析)

    学习C++,特别是C++STL部分,重点不是学习如何去使用STL,而是知道其底层原理是怎么样,是怎么去实现。因此,本篇文章带来是对C++string模拟实现。...一.模拟实现构造函数 对于构造函数,在官方库C99有下面种类:  我们主要实现是 string(); string(const char* s); string(const string&...在C/C++,当小类型于相较大类型做运算时,小类型会向大类型提升,比如int跟double做运算时,int会提升为double。 其解决方法就是,将pos强制转换成int类型。...还有就是,在C++string类,end类型就是size_t,我们既然要模拟实现string,我们就遵循规则。那么我们该如何取解决这个问题呢? 好办!...那就是s2要修改数据时候,就会额外给s2一个空间。这就跟操作系统父子进程概念类似! 本篇文章结束~这就是模拟实现string详细过程,如果有什么不懂可以下方评论留言~喜欢朋友可以点个收藏~

    84520

    封装、继承、多态、重载:C++强大特性与代码设计

    这里写目录标题 封装 C语言封装风格 C++封装 继承 多态 多态实现 虚函数概念: 虚表指针 overload overwrite override 抽象类 重载 封装 C++封装是一种面向对象编程概念...封装可以提供更好代码组织和管理方式,同时也增强了代码安全性,因为外部代码无法直接修改和访问类内部数据。 C语言封装风格 当单一变量无法完成描述需求时候,结构体类型解决了这问题。...C++继承有以下几种类型: 公有继承(public inheritance):派生类继承了基类公有成员和保护成员,并且这些成员在派生类访问权限与基类一样。...多态 C++多态是面向对象编程一个重要概念,它允许使用指针或引用来处理不同类型对象,而实际上执行是根据对象类型动态选择相关操作。多态性可以提高代码灵活性、可复用性和可扩展性。...C++多态性主要通过虚函数(virtual function)和运行时类型识别(runtime type identification)两个机制来实现: 虚函数:在基类声明虚函数,并在派生类中进行重写

    32510

    《挑战30天C++入门极限》C++多态与虚函数使用

    C++多态与虚函数使用   类多态特性是支持面向对象语言最主要特性,有过非面向对象语言开发经历的人,通常对这一章节内容会觉得不习惯,因为很多人错误认为,支持类封装语言就是支持面向对象...,其实不然,Visual BASIC 6.0 是典型非面向对象开发语言,但是它的确是支持类,支持类并不能说明就是支持面向对象,能够解决多态问题语言,才是真正支持面向对象开发语言,所以务必提醒有过其它非面向对象语言基础读者注意...多态这个概念稍微有点模糊,如果想在一开始就想用清晰用语言描述它,让读者能够明白,似乎不太现实,所以我们先看如下代码: //例程1 #include using...+是允许派生类重载基类成员函数,对于类重载来说,明确,不同类对象,调用其类成员函数时候,系统是知道如何找到其类同名成员,上面代码a.ShowMember();,即调用是Vehicle...,当调用DelPN(a);后,在析构时候,系统成功的确定了先调用Car类析构函数,而如果将析构函数virtual修饰去掉,再观察结果,会发现析构时候,始终只调用了基类析构函数,由此我们发现,多态特性

    70110
    领券