详细分析C++ 多态和虚函数

多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。

C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。

下面的实例中,基类 Shape 被派生为两个类,如下所示:

#include <iostream>
using namespace std;

class Shape {
  protected:
   int width, height;
  public:
   Shape( int a=0, int b=0)
   {
     width = a;
     height = b;
   }
   int area()
   {
     cout << "Parent class area :" <<endl;
     return 0;
   }
};
class Rectangle: public Shape{
  public:
   Rectangle( int a=0, int b=0):Shape(a, b) { }
   int area ()
   {
     cout << "Rectangle class area :" <<endl;
     return (width * height);
   }
};
class Triangle: public Shape{
  public:
   Triangle( int a=0, int b=0):Shape(a, b) { }
   int area ()
   {
     cout << "Triangle class area :" <<endl;
     return (width * height / 2);
   }
};
// 程序的主函数
int main( )
{
  Shape *shape;
  Rectangle rec(10,7);
  Triangle tri(10,5);

  // 存储矩形的地址
  shape = &rec;
  // 调用矩形的求面积函数 area
  shape->area();

  // 存储三角形的地址
  shape = &tri;
  // 调用三角形的求面积函数 area
  shape->area();

  return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

Parent class area
Parent class area

导致错误输出的原因是,调用函数 area() 被编译器设置为基类中的版本,这就是所谓的静态多态,或静态链接 - 函数调用在程序执行前就准备好了。有时候这也被称为早绑定,因为 area() 函数在程序编译期间就已经设置好了。

但现在,让我们对程序稍作修改,在 Shape 类中,area() 的声明前放置关键字 virtual,如下所示:

class Shape {
  protected:
   int width, height;
  public:
   Shape( int a=0, int b=0)
   {
     width = a;
     height = b;
   }
   virtual int area()
   {
     cout << "Parent class area :" <<endl;
     return 0;
   }
};

修改后,当编译和执行前面的实例代码时,它会产生以下结果:

Rectangle class area
Triangle class area

此时,编译器看的是指针的内容,而不是它的类型。因此,由于 tri 和 rec 类的对象的地址存储在 *shape 中,所以会调用各自的 area() 函数。

正如您所看到的,每个子类都有一个函数 area() 的独立实现。这就是多态的一般使用方式。有了多态,您可以有多个不同的类,都带有同一个名称但具有不同实现的函数,函数的参数甚至可以是相同的。

虚函数

虚函数 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。

我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。

纯虚函数

您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。

我们可以把基类中的虚函数 area() 改写如下:

class Shape {
  protected:
   int width, height;
  public:
   Shape( int a=0, int b=0)
   {
     width = a;
     height = b;
   }
   // pure virtual function
   virtual int area() = 0;
};

= 0 告诉编译器,函数没有主体,上面的虚函数是纯虚函数。

以上就是详细分析C++ 多态和虚函数的详细内容,更多关于C++ 多态和虚函数的资料请关注我们其它相关文章!

(0)

相关推荐

  • C++中的多态与虚函数的内部实现方法

    1.什么是多态 多态性可以简单概括为"一个接口,多种行为". 也就是说,向不同的对象发送同一个消息, 不同的对象在接收时会产生不同的行为(即方法).也就是说,每个对象可以用自己的方式去响应共同的消息.所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数.这是一种泛型技术,即用相同的代码实现不同的动作.这体现了面向对象编程的优越性. 多态分为两种: (1)编译时多态:主要通过函数的重载和模板来实现. (2)运行时多态:主要通过虚函数来实现. 2.几个相关概念 (1)覆盖.

  • c++语言中虚函数实现多态的原理详解

    前言 自上一个帖子之间跳过了一篇总结性的帖子,之后再发,今天主要研究了c++语言当中虚函数对多态的实现,感叹于c++设计者的精妙绝伦 c++中虚函数表的作用主要是实现了多态的机制.首先先解释一下多态的概念,多态是c++的特点之一,关于多态,简而言之就是 用父类的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数,这种方法呢,可以让父类的指针具有多种形态,也就是说不需要改动很多的代码就可以让父类这一种指针,干一些很多子类指针的事情,这里是从虚函数的实现机制层面进行研究 在写这篇帖子之前

  • C++中继承与多态的基础虚函数类详解

    前言 本文主要给大家介绍了关于C++中继承与多态的基础虚函数类的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 虚函数类 继承中我们经常提到虚拟继承,现在我们来探究这种的虚函数,虚函数类的成员函数前面加virtual关键字,则这个成员函数称为虚函数,不要小看这个虚函数,他可以解决继承中许多棘手的问题,而对于多态那他更重要了,没有它就没有多态,所以这个知识点非常重要,以及后面介绍的虚函数表都极其重要,一定要认真的理解~ 现在开始概念虚函数就又引出一个概念,那就是重写(覆

  • 深入解析C++中的虚函数与多态

    1.C++中的虚函数C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有"多种形态",这是一种泛型技术.所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法.比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议. 对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Tab

  • 深入浅析C++多态性与虚函数

    派生一个类的原因并非总是为了继承或是添加新的成员,有时是为了重新定义基类的成员,使得基类成员"获得新生".面向对象的程序设计真正的力量不仅仅是继承,而且还在于允许派生类对象像基类对象一样处理,其核心机制就是多态和动态联编. (一)多态性 多态是指同样的消息被不同的对象接收时导致不同的行为.所谓消息是指对类成员函数的调用,不同的行为是指的不同的实现,也就是调用了不同的函数. 1)多态的分类 广义上说,多态性是指一段程序能够处理多种类型对象的能力.在C++中,这种多态性可以通过重载多态(函

  • 详细分析C++ 多态和虚函数

    多态按字面的意思就是多种形态.当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态. C++ 多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数. 下面的实例中,基类 Shape 被派生为两个类,如下所示: #include <iostream> using namespace std; class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a;

  • C++的多态和虚函数你真的了解吗

    目录 一.C++的面试常考点 二.阿里真题 2.1 真题一 (1)虚函数表vtbl (2)构造一个派生类对象的过程 (3)析构一个派生类对象的过程 2.2 真题二 2.3 真题三 2.4 真题四 2.5 真题五 三.小结 总结 一.C++的面试常考点 阿里虽然是国内Java的第一大厂但是并非所有的业务都是由Java支撑,很多服务和中下层的存储,计算,网络服务,大规模的分布式任务都是由C++编写.在阿里所有部门当中对C++考察最深的可能就是阿里云. 阿里对C++的常考点: 1.STL 容器相关实现

  • 深入了解C++的多态与虚函数

    目录 1.多态的机制与虚函数的机制 1.1 多态的机制 1.2 虚函数的机制 1.3虚函数表的结构图 1.4 动态多态实现的三个前提件(很重要) 2.多态实例应用 3.多态的巨大问题与虚析构 3.1代码举例说明 3.2代码实现 4.纯虚函数与抽象类 4.1纯虚函数语法格式 4.2纯虚函数的定义 4.3抽象类的应用实例 1.多态的机制与虚函数的机制 1.1 多态的机制 1.当在类中使用virtual声明一个函数为虚函数时,在编译时,编译器会自动在基类中默默地安插一个虚函数表指针,同时的.rodat

  • C++的多态与虚函数你了解吗

    目录 多态性 虚函数 总结 多态性 多态性是面向对象程序设计的关键技术之一,若程序设计语言不支持多态性,不能称为面向对象的语言,利用多态性技术,可以调用同一个函数名的函数,实现完全不同的功能 在C++中有两种多态性: 编译时的多态 通过函数的重载和运算符的重载来实现的 运行时的多态性 运行时的多态性是指在程序执行前,无法根据函数名和参数来确定该调用哪一个函数,必须在程序执行过程中,根据执行的具体情况来动态地确定:它是通过类继承关系public和虚函数来实现的,目的也是建立一种通用的程序:通用性是

  • C++ 多态虚函数的底层原理深入理解

    目录 1 多态的基本概念 1.1 什么是多态? 1.2 怎么实现多态 2 虚函数的底层原理 1 多态的基本概念 1.1 什么是多态? 多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为,通常是父类调用子类的重写函数,在C++中就是 父类指针指向子类对象,此时父类指针的向下引用就可以实现多态 比如看下面的代码: class Animal { public: //虚函数 virtual void speak() { cout << "动物在说话" <<

  • C++中虚函数与纯虚函数的用法

    本文较为深入的分析了C++中虚函数与纯虚函数的用法,对于学习和掌握面向对象程序设计来说是至关重要的.具体内容如下: 首先,面向对象程序设计(object-oriented programming)的核心思想是数据抽象.继承.动态绑定.通过数据抽象,可以使类的接口与实现分离,使用继承,可以更容易地定义与其他类相似但不完全相同的新类,使用动态绑定,可以在一定程度上忽略相似类的区别,而以统一的方式使用它们的对象. 虚函数的作用是实现多态性(Polymorphism),多态性是将接口与实现进行分离,采用

  • C++虚函数及虚函数表简析

    C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有"多种形态",这是一种泛型技术.所谓泛型技术,说白了就是试图使用不变的代码来实现可变的算法.比如:模板技术,RTTI技术,虚函数技术,要么是试图做到在编译时决议,要么试图做到运行时决议. 关于虚函数的使用方法,我在这里不做过多的阐述.大家可以看看相关的C++的书籍.在这篇文章中,我只想从虚函数的实现机制上面为大家 一个

  • 详解C++纯虚函数与抽象类

    1.虚函数 1.1虚函数简介 虚函数可以毫不夸张的说是C++最重要的特性之一,我们先来看一看虚函数的概念. 在基类的定义中,定义虚函数的一般形式为: virtual 函数返回值类型 虚函数名(形参表) { 函数体 } 为什么说虚函数是C++最重要的特性之一呢,因为虚函数承载着C++中动态联编的作用,也即多态,可以让程序在运行时选择合适的成员函数.虚函数必须是类的非静态成员函数(且非构造函数),其访问权限是public.那么:  (1)为什么类的静态成员函数不能为虚函数?  如果定义为虚函数,那么

随机推荐