多态性可以简单的概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,他是面向对象编程领域的核心概念。多态(polymorphisn),字面意思多种形态。
c++多态性是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),或者称为重写(重写的话可以有两种,直接重写成员函数和重写虚函数,只有重写了虚函数才能算作是体现了c++多态性)。而重载则是允许有多个同名的函数,这些函数的参数列表不同,允许参数个数不同,参数类型不同,或者两者都不同。编辑器会根据这些函数的不同列表,将同名的函数的名称做修饰,从而生成一些不同名称的预处理函数,来实现同名函数调用时的重载问题(C++用名称压扎技术来改变函数名区分参数不同的同名函数。名称压扎是一系列代码被附加到函数名上以表决参数类型以及他们出现的次序,名称压扎对编程来说是看不到的,它在编译过程中悄悄进行,在连接过程默默使用,名称压扎不是C++标准,所以哥哥编译器的名称压扎方案可能不同)。但这并没有体现多态性。
多态与非多态的实质区别就是函数地址是早绑定还是晚绑定。如果函数的调用,在编译器编译期间就可以确定函数的调用地址,并产生代码,是静态的,就是说地址是早绑定的。而如果函数调用的地址不能再编译器期间确定,需要在运行时才确定,这就属于晚绑定。
多态的作用是什么?封装可以使得代码模块化,继承可以扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用。也就是说,不论传递过来的究竟是哪个类的对象,函数都能够通过同一个接口调用到适应各自对象的实现方法。
最常见的用法就是声明基类的指针,利用该指针指向任意一个子类对象,调用相应的虚函数,可以根据指向的子类的不同而实现不同的方法。如果没有使用虚函数的话,即没有利用C++多态性,则利用基类指针调用相应的函数时候,将总被限制在基类函数本省,而无法调用到子类中被重写过的函数。因为没有多态性,函数调用的地址将是一定的,二固定的地址将始终调用到同一个函数,这就无法实现一个接口,多种方法的目的了。
#include <iostream.h>
class Animal
{
public:
void eat(){
cout << "animal eat" << endl;
}
void sleep(){
cout << "animal sleep" << endl;
}
virtual void breathe(){
cout << "animal breathe" << endl;
}
};
class Fish : public Animal
{
public:
void sleep(){
cout << "fish sleep" << endl;
}
void breathe(){
cout << "fish breathe" << endl;
}
};
void main()
{
Animal an;
Fish fs;
Animal *p = &an;
p -> sleep();
p -> breathe();
p = &fs;
p -> sleep();
p -> breathe();
Fish *p = (Fish *)&an;
p -> sleep();
p -> breathe();
}
animal sleep
animal breathe
animal sleep
fish breathe
fish sleep
animal breathe
第一个p -> sleep()和p -> breathe()都很好理解,本身是基类指针,指向的又是基类对象,调用的都是基类本身的函数,因此输出结果就是animal sleep 和 animal breathe;
第二个输出结果是animal sleep和fish breathe,p -> sleep()和p -> breathe()则是基类指针执行子类对象,正是体现多态的用法,p->sleep()由于是个基类指针,指向是一个固定偏移量的函数,因此此时指向的就只能是基类的sleep()函数的代码了,因此输出的结果还是animal sleep。而p->breathe()指针是基类指针,指向的breathe()是一个虚函数,由于每个虚函数都有一个虚函数列表,此时,p调用breathe()并不是直接调用函数,而是通过虚函数列表找到相应的函数的地址,因此,根据指向的对象不同,函数的地址也将不同,这里将找到对应的子类的breathe()函数的地址,因此输出的结果也会是子类的结果fish breathe.
第三个输出结果是fish sleep和animal breathe,这是一个用字咧的指针去指向一个强制类型转换为子类的基类对象。结果,并不是很理解这种用法,从原理上来解释,由于B是子类指针,虽然被赋予了基类对象地址,但是p->sleep()在调用的时候,由于地址偏移量固定,偏移量是子类对象的偏移量,于是即使在指向了一个基类对象的情况下,还是调用到了子类的函数,虽然可能从始到终都没有子类对象的实例化出现。而p->breathe()的调用,可能还是因为C++多态性的原因,由于指向的是一个基类对象,通过虚函数列表的引用,找到了基类中breathe()函数的地址,因此调用了基类的函数。由此可见多态性的强大,可以适应各种变化,不论指针是基类的还是子类的,都能找到正确的实现方法(另一种理解:虚函数表指针是保存在类的实例中的,每个实例都有一个虚函数表指针,而一般的方法则和类的实例无关,函数表指针不保存在实例中,即使没有生成类的实例,一般方法的函数表仍然存在)。
分享到:
相关推荐
### C++多态性与虚函数知识点解析 #### 一、多态性的概念 多态性是面向对象编程的一个核心特性,它允许我们通过基类的接口来操作派生类的对象。这种特性使得代码更加灵活且易于扩展。在C++中,多态性主要通过虚函数...
"c++多态性答案" 根据提供的文件信息,我们可以总结出以下知识点: 1. C++支持两种多态性:编译时多态性和运行时多态性。编译时多态性通过函数重载和模板实现,而运行时多态性通过虚函数实现。 2. 虚函数的声明...
关于c++多态性的讲解 对于初学c++者有用。。。
【实验报告——C++中的多态性】 在C++中,多态性是面向对象编程的一个核心特性,它允许我们使用一个基类的指针或引用来调用派生类中重写的方法,从而实现不同类对象的统一处理。本实验报告主要探讨了如何在C++中...
在C++编程语言中,多态性是面向对象编程的核心特性之一,允许不同的对象对同一消息作出不同的响应。本实验报告主要围绕C++中的多态性展开,涉及到构造函数、析构函数、虚函数以及抽象类和纯虚函数的应用。 首先,...
【C++多态性相关习题解析】 C++的多态性是面向对象编程中的一个核心概念,它允许我们使用一个基类类型的指针或引用去调用派生类的对象的成员函数,使得代码更加通用和灵活。多态性主要通过虚函数(virtual ...
C++多态性是面向对象编程的一个核心特性,它允许我们设计更加灵活和可扩展的程序。在C++中,多态性主要通过虚函数和纯虚函数来实现,为对象提供了多种表现形式的能力。本课件将深入探讨这一主题,并提供相关的代码...
【C++多态性相关习题解析】 在C++编程语言中,多态性是面向对象编程的一个核心特性,它允许我们使用一个基类指针或引用去调用派生类的方法,使得代码更加灵活和可扩展。多态性主要通过虚函数(virtual functions)...
**C++多态性和虚函数知识点详解** C++语言提供了两种多态性,分别是编译时多态性和运行时多态性。编译时多态性主要通过函数重载和模板来实现,编译器在编译阶段就能确定调用哪个函数。而运行时多态性则依赖于虚函数...
在C++编程语言中,多态性是面向对象编程的核心特性之一,它允许不同类型的对象对同一消息作出不同的响应。本实验报告详细介绍了如何利用...在实践中不断调试和修正错误有助于提高编程技能,增强对C++多态性机制的理解。
C++多态性的样例程序由于事先对各种人的任务已作了规定,因此,在得到同一个消息时,各种人都知道自己应当怎么做(工作机制事先安排),这就是多态性。可以设想如果不利用多态性那么校长就要分别给学生、家长、教师...
c++课件 多态性与虚函数
### C++中的多态性和虚函数 在C++编程语言中,多态性是一种重要的特性,它允许子类对象可以被当作其父类对象来处理,从而极大地提高了代码的灵活性和可扩展性。多态性的实现主要依赖于虚函数机制。下面我们将详细...
《C++中的多态性分析及其作用》 多态性是C++编程中一个核心的概念,它赋予了程序更高的灵活性和可扩展性。在本文中,我们将深入探讨多态性的定义、类型、实现方式以及运算符重载等相关知识点。 1. 多态性的定义 多...
### 多态性在C++中的应用实例解析 #### 一、多态性的概念与重要性 多态性是面向对象编程(OOP)中的一个核心特性,它允许子类对象可以被当作父类对象来处理,即父类的指针或引用可以指向其任何派生类的对象。通过...
在C++编程语言中,多态性(Polymorphism)是一种关键特性,它允许不同类型的对象对同一种消息做出不同的响应。多态性是面向对象编程的三大特性之一,另外两个是封装和继承。本教程将深入探讨C++中的多态性,特别是...
第9章 多态性与虚函数 本章学习要求: 虚函数 多态性 静态与动态联编 9.1 多态性的概念 9.2 虚函数 9.3 静态绑定与动态绑定 9.4 纯虚函数和抽象类
在C++中,多态性是面向对象编程的重要特性,它允许我们使用基类指针或引用调用派生类的成员函数。以下是对标题和描述中涉及知识点的详细解释: 1. **成员函数调用**: - 当通过对象直接调用成员函数时,会调用该...
主要简述了c++中的多态性,附上代码,详细简述了c++中的多态性,请好好看!