函数重写:(在子类中重写父类中的函数)

  父类中被重写的函数  依然会继承  给子类。

  子类中重写的函数将覆盖父类中的函数。

  通过作用域分辨符  ::  可以访问到父类中的函数。

  例如:

  

#include <iostream>
#include <string> using namespace std; class parent
{
public:
void parent_func(int i , int j)
{
cout << "parent_func(int i , int j)"<<i<<','<<j<<endl;
}
}; class subClass : public parent
{
public:
void parent_func(int i , int j)//重写父类中的 void parent_func(int i , int j)
{
cout << "parent_func(int i , int j)"<<i*<<','<<j*<<endl;
}
}; void doPrint(parent *p)//如果是 subClass 声明的对象,将把 subClass类退化为 parent类来处理(C++ 默认)
{
p->parent_func(, );
}
int main()
{
parent p;
subClass s; s.parent::parent_func(,);//使用作用域分辨符 通过subClass 声明的对象 去调用parent类中的 parent_func(int i , int j)函数 doPrint(&p);//使用 parent类对象
doPrint(&s);//使用subClass类对象
}

运行结果:  

parent_func(int i , int j),
parent_func(int i , int j),
parent_func(int i , int j),

面向对象期望的行为:

  根据实际的对象类型判断如何调用重写函数。

父类指针(引用)指向

  父类对象则调用父类中定义的函数

  子类对象则调用  子类中  重写 的函数

也就是说期望  void doPrint(parent *p) 这个函数调用的时候,如果是父类的对象则直接调用父类中的  void parent_func(int i , int j) 输出结果为:parent_func(int i , int j)1,2

  如果是子类对象 则调用void parent_func(int i , int j) 输出结果为:parent_func(int i , int j)2,4

就需要在 父类中将void parent_func(int i , int j)  改为:virtual void parent_func(int i , int j)  表明此函数为   虚函数   子类通过继承的关系 也将把void parent_func(int i , int j)  修改为  虚函数

  -通过virtual 支持多态(C++ 中实现多态的唯一方法)

  -被virtual 声明的函数被重写后具备多态的特性

  -被virtual 关键字声明的函数叫做虚函数。

  修改代码如下:  

#include <iostream>
#include <string> using namespace std; class parent
{
public:
virtual void parent_func(int i , int j)
{
cout << "parent parent_func(int i , int j)"<<i<<','<<j<<endl;
}
}; class subClass : public parent
{
public:
void parent_func(int i ,int j)//重写父类中的 void parent_func(int i , int j)
{
cout << "subClass parent_func(int i , int j)"<<i*<<','<<j*<<endl;
}
}; void doPrint(parent *p)
{
p->parent_func(, ); //根据对象类型判断如何调用重写函数。
}
int main()
{
parent p;
subClass s; doPrint(&p);//使用 parent类对象
doPrint(&s);//使用subClass类对象
}

运行结果:  

parent  parent_func(int i , int j),
subClass parent_func(int i , int j),

多态存在的意义:

  -多态在程序运行的过程中展现。

  -函数重写必须实现多态,否则无意义

  -是面向对象 组件化程序设计  的基础特性

静态联编:

  在编译的期间就确定了具体的函数调用(重载函数)

动态联编:

  在程序运行后才能确定函数的调用(重写函数)

例如:

#include <iostream>
#include <string> using namespace std; class parent
{
public:
virtual void func(int i )
{
cout << "func(int i )"<<i<<endl;
}
virtual void func(int i , int j)
{
cout << "parent func(int i , int j)"<<i<<','<<j<<endl;
}
virtual void func(int i , int j,int k)
{
cout << "parent func(int i , int j,int k)"<<i<<','<<j<<','<<'k'<<endl;
}
}; class subClass : public parent
{
public:
void func(int i , int j) //等价于 virtual void func(int i , int j)
{
cout << "subClass func(int i , int j)"<<i+j<<endl;
}
void func()
{
cout <<" void func()"<<endl;
}
}; void doPrint(parent *p)
{
p->func(, ); //实现多态特性
}
int main()
{
parent p;
subClass s; p.func();//静态联编
p.func(,);//静态联编
p.func(,,);//静态联编 cout <<endl;
s.func(,);//静态联编 编译时就知道了调用函数,最终会调用到,subClass 类中的 void func(int i , int j) 函数 doPrint(&p);//展现动态联编
doPrint(&s);//展现动态联编
}

运行结果:  

func(int i )
parent func(int i , int j),
parent func(int i , int j,int k),,k subClass func(int i , int j)
parent func(int i , int j),
subClass func(int i , int j)

C++ 多态、虚函数(virtual 关键字)、静态联编、动态联编的更多相关文章

  1. C++构造函数和析构函数调用虚函数时都不会使用动态联编

    先看一个例子: #include <iostream> using namespace std; class A{ public: A() { show(); } virtual void ...

  2. 多态&虚函数

     (1).对象类型:           a.静态类型:对象声明时的类型,编译的时候确定           b.动态类型:对象的类型是运行时才能确定的 class A {}; class B:pub ...

  3. C++: 多态 虚函数

    一.多态: 1.多态是什么:具有不同功能的函数可以用同一个函数名 2.静态多态:程序编译时决定,通过函数重载实现. 3.动态多态:程序运行时决定,通过虚函数实现. 二.虚函数: 1.引入目的:可以通过 ...

  4. C#中的虚函数virtual

    简单介绍虚函数virtual 在某基类中声明 virtual 并在一个或多个派生类中被重新定义的成员函数称为虚函数. 虚函数的作用就是实现多态性(Polymorphism),多态性是将接口与实现进行分 ...

  5. C#虚函数virtual详解

    在面向对象编程中,有两种截然不同的继承方式:实现继承和接口继承.在实现继承时候,在Java中,所有函数默认都是virtual的,而在C#中所有函数并不默认为virtual的,但可以在基类中通过声明关键 ...

  6. 十万个为什么:现在还没发现“虚函数virtual”和多态性的优点,估计是因为我还没有编程序吧。

    十万个为什么:现在还没发现“虚函数virtual”和多态性的优点,估计是因为我还没有编程序吧.

  7. C++继承-重载-多态-虚函数

    C++ 继承 基类 & 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数.定义一个派生类,我们使用一个类派生列表来指定基类.类派生列表以一个或多个基类命名,形式如下: ...

  8. C++基础 (6) 第六天 继承 虚函数 虚继承 多态 虚函数

    继承是一种耦合度很强的关系 和父类代码很多都重复的 2 继承的概念 3 继承的概念和推演 语法: class 派生类:访问修饰符 基类 代码: … … 4 继承方式与访问控制权限 相对的说法: 爹派生 ...

  9. 虚函数virtual

    简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离:用形象的语言来解释就是实现以共同 ...

随机推荐

  1. DB 分库分表(1):拆分实施策略和示例演示

    DB 分库分表(1):拆分实施策略和示例演示 第一部分:实施策略 1.准备阶段 对数据库进行分库分表(Sharding化)前,需要开发人员充分了解系统业务逻辑和数据库schema.一个好的建议是绘制一 ...

  2. (十七)C语言之变量

  3. LeetCode 86. 分隔链表(Partition List)

    题目描述 给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前. 你应当保留两个分区中每个节点的初始相对位置. 示例: 输入: head = 1-> ...

  4. Appium+Robotframework实现iOS应用的自动化测试

    Appium+Robotframework实现iOS应用的自动化测试 连接地址: 地址:https://blog.csdn.net/wd168/article/month/2016/06 1.http ...

  5. javascript 生成img标签的3种方式(对象、方法、html)

    <div id="d1"></div> <script> //HTML function a(){ document.getElementByI ...

  6. [zookeeper]ZooInspector的使用

    一.背景   Zookeeper作为常用的集群协调者组件被广泛应用,尤其是在大数据生态圈中:   Zookeeper集群存储各个节点信息,包括:Hadoop.Hbase.Storm.Kafka等等: ...

  7. 八十四:redis之redis的集合、哈希操作

    set集合操作 添加元素:sadd set value1 value2... 查看元素:smembers set 移除元素:srem set member 查看集合中的元素个数:scard set 获 ...

  8. kvm热迁移(4)

    一.迁移简介 迁移分为热迁移和冷迁移,冷迁移是在机器关机的状态下进行迁移,具体操作在之前的博客有体现.热迁移是在机器处于开机状态进行迁移,本次博客主要讲解热迁移. 系统的迁移是指把源主机上的操作系统和 ...

  9. mariadb面试

    [mariadb主从架构的工作原理] 主节点写入数据以后,保存到二进制文件中,从节点生成IO线程和sql线程,IO线程请求读取二进制文件:主节点生成的dump线程,将数据发送到中继日志中,sql线程读 ...

  10. 【Linux】【二】linux 压缩文件(txt)、查看压缩文件内容、解压缩文件、

    通过Xshell 压缩文件.解压缩文件 gzip tools.txt 压缩[tools.txt]文件 zcat tools.txt.gz   查看压缩文件[tools.txt.gz]内容 gunzip ...