简述C++中的多态机制
前言
封装性,继承性,多态性是面向对象语言的三大特性。其中封装,继承好理解,而多态的概念让许多初学者感到困惑。本文将讲述C++中多态的概念以及多态的实现机制。
什么是多态?
多态就是多种形态,就是许多情况下可以互换地使用基类型和派生类型的多种形态。
多态的实现
依赖于动态绑定机制
动态绑定机制相关
动态绑定是函数实际参数和形式参数绑定的一种方式,它是指我们能够在函数接口中使用继承层次中任意类型的对象,无需关心对象的具体类型。
动态执行接口函数的对象参数的哪个函数得在程序实际执行的时候才能确定
C++中默认不使用动态绑定,要触发动态绑定必须满足两个条件:
1. 接口函数的形式参数必须是引用类型或者指针类型
2. 动态执行函数(对象参数的成员函数而非接口函数)必须是声明为虚成员函数。
代码实例一
下面代码创建基类对象a,然后创建其派生对象b,当将a,b作为参数传入函数printNum()后,函数让它们分别调用自己的函数getNum():
#include <iostream> using namespace std; // 基类
class A {
public:
A() {a=;}
// **需要动态执行的函数必须声明为虚函数,满足了上条件2。
virtual int getNum() {
return a;
}
private:
int a;
}; // 派生类
class B : public A {
public:
B() {b=;}
// 基类中已经声明过为虚函数了不需要再次声明
int getNum() {
return b;
}
private:
int b;
}; // **接口函数形参声明为引用类型,满足了上条件1。
void printNum(A & a) {
// 当实参为基类对象则调用基类对象的getNum,实参为派生类对象则调用派生类对象的getNum。
cout << a.getNum() << endl;
} int main()
{
A a;
B b; printNum(a);
printNum(b); return ;
}
运行结果:
可以观察到顺利实现了动态绑定,a b分别执行自己的getNum() 函数。
代码实例二
下面代码同样创建基类对象a,然后创建其派生对象b,当将a,b作为参数传入函数printNum()后,函数让它们分别调用自己的函数getNum()(但本例接口函数的形式参数改成了值类型 ):
#include <iostream> using namespace std; // 基类
class A {
public:
A() {a=;}
// **需要动态执行的函数必须声明为虚函数,满足了上条件2。
virtual int getNum() {
return a;
}
private:
int a;
}; // 派生类
class B : public A {
public:
B() {b=;}
// 基类中已经声明过为虚函数了不需要再次声明
int getNum() {
return b;
}
private:
int b;
}; // **接口函数形参声明为值类型,不满足上条件1。
void printNum(A a) {
// 未有实现动态绑定,因此不论实参是何种类型,均执行基类的getNum()函数。
cout << a.getNum() << endl;
} int main()
{
A a;
B b; printNum(a);
printNum(b); return ;
}
运行结果:
可以观察到没有实现动态绑定,a b都执行a的getNum() 函数。这意味着,对象本身并不支持多态,它刚进入函数就被彻底地转换成了形参类型。因此,实现多态要靠的是对象的指针或者引用,而不是对象本身。这也是C++ Primer一书中不断强调的东西。
说明
1. 派生类和基类的虚函数类型要一致,只有一种例外 --- 返回对基类类型的引用的虚函数。派生类中的虚函数可以返回基类函数所返回类型的派生类的引用。
2. 基类和派生类的虚函数的默认实参要相同,不然会引起混淆。
小结
封装保证了类的重用( 安全方面 ),继承实现了类的重用,多态则实现了接口的重用。这三个机制体现了C++代码的可重用性,反映了C++在处理大型程序的优势。
简述C++中的多态机制的更多相关文章
- c++中的多态机制
目录 1 背景介绍 2 多态介绍 2-1 什么是多态 2-2 多态的分类 2-3 动态多态成立的条件 2-4 静态联编和动态联编 2-5 动态多态的实现原理 2-6 虚析构函数 ...
- 深度分析:理解Java中的多态机制,一篇直接帮你掌握!
Java中的多态 1 多态是什么 多态(Polymorphism)按字面的意思就是"多种状态".在面向对象语言中,接口的多种不同的实现方式即为多态.用白话来说,就是多个对象调用同一 ...
- 第二十二篇:C++中的多态机制
前言 封装性,继承性,多态性是面向对象语言的三大特性.其中封装,继承好理解,而多态的概念让许多初学者感到困惑.本文将讲述C++中多态的概念以及多态的实现机制. 什么是多态? 多态就是多种形态,就是许多 ...
- java中实现多态的机制是什么?
多态性是面向对象程序设计代码重用的一个重要机制,我们曾不只一次的提到Java多态性.在Java运行时多态性:继承和接口的实现一文中,我们曾详细介绍了Java实现运行时多态性的动态方法调度:今天我们再次 ...
- c++中虚多态的实现机制
c++中虚多态的实现机制 參考博客:http://blog.csdn.net/neiloid/article/details/6934135 序言 证明vptr指针存在 无继承 单继承无覆盖 单继承有 ...
- Java多态机制和继承中重写重载
关于Java中多态机制 http://www.cnblogs.com/chenssy/p/3372798.html 这篇博文讲的很透彻 大体意思是 多态定义: 多态就是指程序中定义的引用变量所指向的具 ...
- 【C++】异常简述(一):C语言中的异常处理机制
人的一生会遇到很多大起大落,尤其是程序员. 程序员写好的程序,论其消亡形式无非三种:无疾而终.自杀.他杀. 当然作为一名程序员,最乐意看到自己写的程序能够无疾而终,因此尽快的学习异常处理机制是非常重要 ...
- 深入理解Java多态机制
从字节码层面来看,Java中的所有方法调用,最终无外乎转换为如下几条调用指令. invokestatic: 调用静态方法. invokespecial: 调用实例构造器<init>方法,私 ...
- 转载:C#中的多态
原文地址 http://www.cnblogs.com/jhxk/articles/1644018.html 感谢博主分享! 之前看到过类似的问题:如果面试时主考官要求你用一句话来描述多态,尽可能的 ...
随机推荐
- java 自定义log类
目录机构如下: package tpf.common; import org.apache.log4j.*; import java.io.File; import java.net.URL; pub ...
- Red is good(bzoj 1419)
Description 桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元.可以随时停止翻牌,在最优策略下平均能得到多少钱. Input 一 ...
- AC日记——[SDOI2015]星际战争 洛谷 P3324
题目描述 3333年,在银河系的某星球上,X军团和Y军团正在激烈地作战. 在战斗的某一阶段,Y军团一共派遣了N个巨型机器人进攻X军团的阵地,其中第i个巨型机器人的装甲值为Ai.当一个巨型机器人的装甲值 ...
- CSS-点赞爱心小动画
爱心图片: HTML: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> & ...
- Codeforces Gym101606 C.Cued In (2017 United Kingdom and Ireland Programming Contest (UKIEPC 2017))
C Cued In 这个题是打球的.都忘了写的什么了... 代码: 1 #include<iostream> 2 #include<cstring> 3 #include< ...
- Java 界面编程【02】事件注册
聪明出于勤奋,天才在于积累.——华罗庚 对上次的三个问题的个人理解: 1) 程序首先是从main函数开始执行的,假设main 函数不是 static ,就要先实例化这个类,然后调用 main 方法,这 ...
- Springboot构建问题集
最近在搭建框架时遇到很多细节问题,时间久了就很容易忘记,在此记录一下. 1.问题:Warning:java: 来自注释处理程序 'org.antlr.v4.runtime.misc.NullUsage ...
- SQL Server 存储
http://baoqiangwang.blog.51cto.com/1554549/541298/
- Pixhawk之姿态解算篇(1)_入门篇(DCM Nomalize)
一.开篇 慢慢的.慢慢的.慢慢的就快要到飞控的主要部分了,飞控飞控就是所谓的飞行控制呗,一个是姿态解算一个是姿态控制,解算是解算,控制是控制,各自负责各自的任务.我也不懂.还在学习中~~~~ 近期看姿 ...
- electron 缓存目录 禁用缓存
C:\Users\Administrator\AppData\Roaming\linksame // 禁用缓存 app.commandLine.appendSwitch("--disable ...