c实现多态的方法
- 格式:doc
- 大小:11.97 KB
- 文档页数:1
C语⾔中的多态⼀、多态的主要特点1、继承体系下。
继承:是⾯向对象最显著的⼀个特性。
继承是从已有的类中派⽣出新的类,新的类能吸收已有类的数据属性和⾏为,并能扩展新的能⼒,已有类被称为⽗类/基类,新增加的类被称作⼦类/派⽣类。
2、⼦类对⽗类的虚函数进⾏重写。
3、虚表。
在⾯向对象语⾔中,接⼝的多种不同现⽅式即为多态。
同⼀操作作⽤于不同的对象,可以有不同的解释,产⽣不同的执⾏结果,这就是多态性。
简单说就是允许基类的指针指向⼦类的对象。
⼆、代码实现1、C++中的继承与多态1 class Base2 {3 public:4 virtual void fun() {} //基类函数声明为虚函数5 int B1;6 };7 class Derived :public Base //Derived类公有继承Base类8 {9 public:10 virtual void fun() { //函数重写,此时基类函数可以声明为虚函数,也可以不声明11 cout << "D1.fun" << endl;12 }13 int D1;14 };15 int main(){16 Base b1; //创建⽗类对象17 Derived d1;//创建⼦类对象1819 Base *p1 = (Base *)&d1;//定义⼀个⽗类指针,并通过⽗类指针访问⼦类成员20 p1->fun();2122 Derived *p2 = dynamic_cast<Derived*> (&b1); //dynamic_cast⽤于将⼀个⽗类对象的指针转换为⼦类对象的指针或引⽤(动态转换)23 p2->fun();2425 getchar();26 return 0;27 }2. C语⾔实现C++的继承与多态1 typedef void(*FUNC)(); //定义⼀个函数指针来实现对成员函数的继承2 struct _Base //⽗类3 {4 FUNC _fun;//由于C语⾔中结构体不能包含函数,故借⽤函数指针在外⾯实现5 int _B1;6 };7 struct _Derived//⼦类8 {9 _Base _b1;//在⼦类中定义⼀个基类的对象即可实现对⽗类的继承10 int _D1;11 };12 void fb_() //⽗类的同名函数13 {14 printf("_b1:_fun()\n");15 }16 void fd_() //⼦类的同名函数17 {18 printf("_d1:_fun()\n");19 }20 int main() {21 _Base _b1;//定义⼀个⽗类对象_b122 _Derived _d1;定义⼀个⼦类对象_d12324 _b1._fun = fb_;//⽗类的对象调⽤⽗类的同名函数25 _d1._b1._fun = fd_;//⼦类的对象调⽤⼦类的同名函数2627 _Base *_p1 = &_b1;//定义⼀个⽗类指针指向⽗类的对象28 _p1-> _fun(); //调⽤⽗类的同名函数2930 _p1 = (_Base *)&_d1;//让⽗类指针指向⼦类的对象,由于类型不匹配所以要进⾏强转31 _p1->_fun(); //调⽤⼦类的同名函数3233 getchar();34 return 0;35 }。
C++中的封装、继承、多态理解封装(encapsulation):就是将抽象得到的数据和⾏为(或功能)相结合,形成⼀个有机的整体,也就是将数据与操作数据的源代码进⾏有机的结合,形成”类”,其中数据和函数都是类的成员。
封装的⽬的是增强安全性和简化编程,使⽤者不必了解具体的实现细节,⽽只是要通过外部接⼝,特定的访问权限来使⽤类的成员。
封装可以隐藏实现细节,使得代码模块化。
继承(inheritance):C++通过类派⽣机制来⽀持继承。
被继承的类型称为基类或超类,新产⽣的类为派⽣类或⼦类。
保持已有类的特性⽽构造新类的过程称为继承。
在已有类的基础上新增⾃⼰的特性⽽产⽣新类的过程称为派⽣。
继承和派⽣的⽬的是保持已有类的特性并构造新类。
继承的⽬的:实现代码重⽤。
派⽣的⽬的:实现代码扩充。
三种继承⽅式:public、protected、private。
继承时的构造函数:(1)、基类的构造函数不能被继承,派⽣类中需要声明⾃⼰的构造函数;(2)、声明构造函数时,只需要对本类中新增成员进⾏初始化,对继承来的基类成员的初始化,⾃动调⽤基类构造函数完成;(3)、派⽣类的构造函数需要给基类的构造函数传递参数;(4)、单⼀继承时的构造函数:派⽣类名::派⽣类名(基类所需的形参,本类成员所需的形参):基类名(参数表) {本类成员初始化赋值语句;};(5)、当基类中声明有默认形式的构造函数或未声明构造函数时,派⽣类构造函数可以不向基类构造函数传递参数;(6)、若基类中未声明构造函数,派⽣类中也可以不声明,全采⽤缺省形式构造函数;(7)、当基类声明有带形参的构造函数时,派⽣类也应声明带形参的构造函数,并将参数传递给基类构造函数;(8)、构造函数的调⽤次序:A、调⽤基类构造函数,调⽤顺序按照它们被继承时声明的顺序(从左向右);B、调⽤成员对象的构造函数,调⽤顺序按照它们在类中的声明的顺序;C、派⽣类的构造函数体中的内容。
继承时的析构函数:(1)、析构函数也不被继承,派⽣类⾃⾏声明;(2)、声明⽅法与⼀般(⽆继承关系时)类的析构函数相同;(3)、不需要显⽰地调⽤基类的析构函数,系统会⾃动隐式调⽤;(4)、析构函数的调⽤次序与构造函数相反。
C的运行时类型识别实现动态多态性在C语言中,没有原生的运行时类型识别(Runtime Type Identification,RTTI)机制,而RTTI是实现多态性的关键。
然而,我们可以通过一些技巧和约定来模拟实现动态多态性,即在运行时根据对象的类型来决定调用哪个函数。
本文将介绍一种常用的C语言中实现动态多态性的方法。
一、使用函数指针表进行类型识别为了实现运行时类型识别,我们可以使用函数指针表(Function Pointer Table)来存储不同类型对象的函数指针。
函数指针表是一个包含一组函数指针的数组,数组的索引对应于对象的类型。
首先,我们定义一个基础的类型,作为其他类型的父类型,例如Shape类型:```ctypedef struct {void (*draw)();} Shape;```接下来,我们定义继承自Shape的具体类型,例如Rectangle和Circle:```ctypedef struct {Shape shape;int width;int height;} Rectangle;typedef struct {Shape shape;int radius;} Circle;```我们为每个具体类型实现相应的draw函数:```cvoid rectangle_draw() {printf("Drawing rectangle\n");}void circle_draw() {printf("Drawing circle\n");}```然后,我们为每个具体类型创建函数指针表,并将draw函数指针赋值给相应的表项:```cShape shape;shape.draw = rectangle_draw;Shape shape;shape.draw = circle_draw;```现在,我们可以通过调用shape.draw()来动态地调用相应类型的draw函数。
c++三大特征的理解
C++语言的三大特征是封装、继承和多态。
封装是指将数据和操作数据的方法捆绑在一起,以防止外部访
问和不合法修改,从而保证数据的安全性和一致性。
通过封装,可
以隐藏实现细节,使得对象更容易被使用,并且减少了对外部的依赖。
继承是指一个类可以派生出新的类,新的类可以继承原有类的
属性和方法,并且可以添加新的属性和方法。
继承可以提高代码的
复用性,减少重复编码,同时也能够实现多态性。
多态性是指同一个消息被不同的对象接收时,可以产生不同的
行为。
在C++中,多态性可以通过虚函数和纯虚函数来实现。
多态
性使得程序更加灵活,能够根据不同对象的类型来执行不同的操作,从而提高了代码的可扩展性和可维护性。
总的来说,封装、继承和多态是C++语言的三大特征,它们为
面向对象编程提供了强大的支持,使得程序更加模块化、灵活和易
于扩展。
c语言中多态的定义及实现方式C语言是一种面向过程的编程语言,不支持面向对象编程的特性,如多态、继承和封装等。
但是,我们可以通过一些技巧来实现类似于面向对象编程中的多态性。
在本文中,我们将介绍C语言中多态的定义、实现方式以及举出一些例子。
1.多态的定义多态是面向对象编程中的一个重要概念。
它指的是不同对象对同一消息作出不同响应的能力。
在C语言中,我们可以通过函数指针、结构体和联合体等技术来实现多态性。
下面是多态的定义:多态是指在不同的对象上调用同一方法,而这些对象会根据所属类的不同产生不同的行为。
换句话说,多态是指一个接口,多种实现。
1.多态的实现方式在C语言中,我们可以通过以下方式来实现多态性:2.1 函数指针函数指针是指向函数的指针变量。
我们可以将不同的函数指针赋值给同一个函数指针变量,从而实现多态性。
例如:#include <stdio.h>void add(int a,int b){printf("%d + %d = %d\n", a, b, a + b);}void sub(int a,int b){printf("%d - %d = %d\n", a, b, a - b);}int main(){void(*p)(int,int);int a =10, b =5;p = add;p(a, b);p = sub;p(a, b);return0;}在上面的例子中,我们定义了两个函数add和sub,它们实现了两种不同的行为。
我们定义了一个函数指针p,它可以指向这两个函数。
在不同的情况下,我们将p 指向不同的函数,从而实现了多态性。
2.2 结构体结构体是一种自定义的数据类型,它可以包含多个不同类型的成员。
我们可以通过结构体来实现多态性。
例如:#include <stdio.h>typedef struct Animal{void(*speak)();} Animal;typedef struct Cat{Animal base;} Cat;typedef struct Dog{Animal base;} Dog;void cat_speak(){printf("Meow!\n");}void dog_speak(){printf("Woof!\n");}int main(){Cat cat;Dog dog;cat.base.speak = cat_speak;dog.base.speak = dog_speak;cat.base.speak();dog.base.speak();return0;}在上面的例子中,我们定义了一个Animal结构体和两个派生结构体Cat和Dog。
C语言中的封装、继承和多态1. 引言在面向对象编程中,封装、继承和多态是三个核心的概念。
它们是面向对象编程语言中的基本特性,也是设计和开发高质量软件的关键要素。
本文将介绍在C语言中如何实现封装、继承和多态,并对其进行详细解释和说明。
2. 封装封装是面向对象编程中的一种重要概念,它将数据和操作数据的函数封装在一起,形成一个类。
在C语言中,封装可以通过结构体来实现。
结构体可以将多个相关的数据项组合在一起,形成一个逻辑上的整体。
同时,可以通过函数来操作这些数据项,实现对数据的封装。
以下是一个示例代码,演示了如何在C语言中实现封装:#include <stdio.h>typedef struct {int age;char name[20];} Person;void printPerson(Person* p) {printf("Name: %s, Age: %d\n", p->name, p->age);}int main() {Person person;person.age = 20;strcpy(, "John");printPerson(&person);return 0;}在上述代码中,我们定义了一个名为Person的结构体,它包含了一个整型变量age和一个字符数组name。
通过定义一个函数printPerson来打印Person的信息。
在main函数中,我们创建了一个Person类型的变量person,并对其进行赋值和打印。
通过上述代码,我们可以看到封装的好处。
封装可以隐藏数据的具体实现细节,只暴露必要的接口,提高代码的可维护性和可复用性。
3. 继承继承是面向对象编程中的另一个重要概念,它允许一个类继承另一个类的属性和方法。
在C语言中,可以通过结构体嵌套来实现类似继承的效果。
以下是一个示例代码,演示了如何在C语言中实现继承:#include <stdio.h>typedef struct {int age;char name[20];} Person;typedef struct {Person person;int score;} Student;void printStudent(Student* s) {printf("Name: %s, Age: %d, Score: %d\n", s->, s->person.age, s-> score);}int main() {Student student;student.person.age = 20;strcpy(, "John");student.score = 90;printStudent(&student);return 0;}在上述代码中,我们定义了一个名为Person的结构体,它包含了一个整型变量age和一个字符数组name。
c实现多态的方法
多态是面向对象编程中的一个重要概念,它可以让不同的对象对同一消息做出不同的响应。
在C语言中实现多态一般有以下几种方法: 1. 函数指针:定义一个函数指针类型,不同的类型可以指向不
同的函数实现,通过函数指针调用函数实现多态。
2. 结构体与函数指针组合:定义一个结构体,其中包含函数指
针成员,在不同的结构体中实现不同的函数,通过结构体指针调用不同的函数实现多态。
3. 函数指针数组:定义一个函数指针数组,数组中不同的元素
可以指向不同的函数实现,通过数组索引调用不同的函数实现多态。
需要注意的是,在C语言中实现多态需要手动管理内存,因此需要谨慎使用,避免内存泄漏等问题。
- 1 -。