C++中的多态

多态是C++面向对象三大基本特性之一(封装,继承,多态)。多态相对于其它两个特性是相对比较复杂的。

多态又分为静态多态和动态多态,通俗点的解释就是一种表像多种形态(纯粹个人理解)。

静态多态又称编译期多态,即在系统编译期间就可以确定程序将要执行哪个函数。

例如,函数重载,运算符重载

动态多态是利用派生类和虚函数相结合的形式实现运行时的多态,即在系统编译的时候并不知道程序将要调用哪一个函数,只有在运行到这里的时候才能确定接下来会跳转到哪一个函数。

静态多态和动态多态本质的区别:

静态多态----地址早绑定,编译阶段确定函数地址;

动态多态----地址晚绑定,运行阶段确定函数地址;

记得曾经有位老师出过下面一段代码,大概的意思是,每个动物都有自己独特的叫声,有个父类(Animal),有个子类(Dog),请问以下代码能实现狗叫吗?


图1


正确答案是:

这个案例让我终生受用,至少时至今日,我一直都记得一定要重写父类的虚函数,否则是发生不了多态的,下面给出C++中多态的条件

C++中发生多态所必须满足条件:

  • 有父子的继承关系
  • 子类重写父类的函数
  • 父类的指针或者引用,指向子类的对象

最后给出正确的代码示例

#include <iostream>
#include <string>

using namespace std;

class Animal
{
public:
    void virtual Speak()
    {
        cout << "Now, Animal is Speaking!" << endl;
    }
};

class Dog: public Animal
{
public:
    void Speak()
    {
        cout << "Now, Dog is Speaking! Woof,Woof..." << endl;
    }
};

void Speaking(Animal &animal) //Animal &animal = myDog;
{
    animal.Speak();
}

void test()
{
    Dog myDog;
    Speaking(myDog);
}

int main()
{
    test();
    system("pause");
    return 0;
}

但是我也是工作了若干年后,才有了进一步的了解,可以利用Visual Studio自带的开发者命令提示(Developer Command Prompt for VS2013)

  1. 进入到项目文件所在的目录,例如我自己定义的工作目录是(D:\workspace\C++\Polymorphism\Polymorphism), 并确定该文件是否存在
  2. ,这里我的文件名也是Polymorphism.cpp
  3. 使用命令 cl /d1 reportSingleClassLayoutAnimal Polymorphism.cpp

reportSingleClassLayout ----报告单个类布局(很直白的翻译)

Animal----类名(一个类的名字,即关键字class后的名字)

Polymorphism.cpp----文件名

这里,利用开发者管理工具分别查看了Animal类和Dog类(蓝色下划线的Polymorphism.cpp是文件名)

vfptr     ---- v:virtual      f----function      ptr----pointer, 即虚函数指针

vftable ---- v:virtual      f----function      ptr----pointer, 即虚函数表

每个类都有一个虚函数指针,指向一个虚函数表,Animal指向的是&Animal::Speak() ,而Dog指向的是&Dog::Speak,

当用父类的引用指向一个子类的对象时,本例中是(Animal &animal = myDog),其本质还是一个子类的对象,调用animal.Speak()后,其实就是调用&Dog::Speak,而非&Animal::Speak()。

也正是上述蓝色字体的描述,导致了动态多态,这样我们就要可以为每种动物,小鸡,小鸭,小猫……设定不同的叫声

如果去掉代码中virtual关键字(即图1),没有发生多态的原因也可以用以上命令查看:

这里无论是Animal还是Dog的size都变成1了,不会再有虚函数指针和虚函数表的概念了,而函数本身又不占类的size,是单独存储的,自然不会发生多态

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值