Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >虚函数与纯虚函数的区别:深入解析及应用实例

虚函数与纯虚函数的区别:深入解析及应用实例

原创
作者头像
用户11308197
发布于 2024-11-11 05:51:29
发布于 2024-11-11 05:51:29
30500
代码可运行
举报
运行总次数:0
代码可运行

在C++编程中,虚函数和纯虚函数是实现多态性和抽象类的重要工具。虽然它们都属于函数声明的特殊形式,但它们的定义、特性和应用方式却存在显著的差异。本文将深入解析虚函数与纯虚函数的区别,并通过实例展示它们在实际编程中的应用。

一、虚函数

虚函数是指在C++中,被virtual关键字修饰的成员函数。当调用此类函数时,编译器会根据调用对象的实际类型,而不是根据声明类型来调用适当的函数。这种机制使得虚函数能够实现多态性,即相同的函数名在不同的对象上可以表现出不同的行为。

虚函数可以在类中声明,也可以在类的外部声明。编译器会自动将它们转换为虚函数,并在类对象中插入一个指向虚函数表的指针。虚函数表保存了类中所有虚函数的地址,通过虚表指针可以找到对应的函数地址,从而实现动态绑定。

虚函数可以有实现,也可以没有实现。在子类中,虚函数可以被覆盖,也可以不被覆盖。如果子类没有覆盖基类的虚函数,那么当通过基类指针或引用调用该函数时,将调用基类的虚函数实现。

二、纯虚函数

纯虚函数是一种特殊的虚函数,它在声明时除了加上virtual关键字外,还需要加上=0。纯虚函数没有函数体,只提供函数声明,而不提供实际实现。由于编译器不能确定如何实现纯虚函数,因此需要在子类中实现它。

纯虚函数只能在类中声明,而不能在类的外部声明。由于纯虚函数没有实现,因此它所在的类被称为抽象类。抽象类不能实例化对象,只能作为基类为派生类服务。派生类必须实现基类中所有的纯虚函数,否则派生类也将成为抽象类,不能实例化对象。

三、虚函数与纯虚函数的区别
  1. 定义方式:虚函数在定义时在普通函数的基础上加上virtual关键字,而纯虚函数在定义时除了加上virtual关键字外,还需要加上=0
  2. 实现方式:虚函数可以有实现,也可以没有实现;而纯虚函数没有实现,必须在子类中实现。
  3. 使用方式:虚函数可以直接使用,而纯虚函数必须在派生类中实现后才能使用。
  4. 多态性:虚函数和纯虚函数都可以实现多态性,但纯虚函数更多地用于定义抽象接口,而虚函数则用于实现具体的多态行为。
  5. 类类型:包含虚函数的类可以是普通类,也可以是抽象类;而包含纯虚函数的类一定是抽象类。
四、应用实例

以下是一个包含虚函数和纯虚函数的简单示例,展示了它们在实际编程中的应用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cpp复制代码#include <iostream>using namespace std; // 定义一个抽象基类class Shape {public:    // 纯虚函数,定义接口    virtual void draw() = 0;     // 虚函数,可以有实现    virtual void setColor(const string& color) {        cout << "Setting color to " << color << endl;    }}; // 定义一个派生类,实现抽象接口class Circle : public Shape {public:    // 实现纯虚函数    void draw() override {        cout << "Drawing a circle" << endl;    }     // 可以选择覆盖基类中的虚函数,也可以不覆盖    // void setColor(const string& color) override {    //     cout << "Circle color set to " << color << endl;    // }}; int main() {    // 不能直接实例化抽象类    // Shape shape;     // 实例化派生类    Circle circle;     // 调用派生类实现的纯虚函数    circle.draw();     // 调用基类中的虚函数实现,或者派生类中覆盖的实现(如果有的话)    circle.setColor("Red");     return 0;}

在上面的示例中,Shape类是一个抽象基类,它定义了一个纯虚函数draw()和一个虚函数setColor()Circle类是一个派生类,它实现了Shape类中的纯虚函数draw(),并可以选择覆盖基类中的虚函数setColor()(在上面的示例中并没有覆盖)。

通过实例化Circle类对象并调用其成员函数,可以看到虚函数和纯虚函数在实际编程中的应用效果。虚函数setColor()在基类中有实现,派生类可以选择覆盖它;而纯虚函数draw()在基类中没有实现,必须在派生类中实现后才能使用。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
C++一分钟之-虚函数与抽象类
在C++的面向对象编程之旅中,虚函数与抽象类是实现多态性不可或缺的两块基石。它们不仅加深了类层次间的耦合度,还极大地提升了代码的灵活性和可扩展性。本文旨在深入浅出地解析虚函数与抽象类的核心概念、常见问题、易错点及其规避策略,并通过实例代码加以说明。
Jimaks
2024/06/21
1650
解锁C++多态的魔力:灵活与高效的编码艺术(上)
多态性是面向对象编程的重要特性之一,而C++通过虚函数、继承等机制实现了这一强大的功能。多态性使得代码更加灵活和可扩展,允许不同类型的对象以统一的方式进行操作。在本篇文章中,我们将深入探讨C++中多态的实现原理、使用场景及其优劣势,并通过具体代码示例展示如何利用多态来提升代码的可维护性和复用性。
suye
2024/10/18
2610
解锁C++多态的魔力:灵活与高效的编码艺术(上)
从零开始学C++之虚函数与多态(二):纯虚函数、抽象类、虚析构函数
一、纯虚函数 虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数
s1mba
2017/12/28
1.5K0
从零开始学C++之虚函数与多态(二):纯虚函数、抽象类、虚析构函数
C++纯虚函数与抽象类
为什么说虚函数是C++最重要的特性之一呢,因为虚函数承载着C++中动态联编的作用,也即多态,可以让程序在运行时选择合适的成员函数。虚函数必须是类的非静态成员函数(且非构造函数),其访问权限是public。那么: (1)为什么类的静态成员函数不能为虚函数? 如果定义为虚函数,那么它就是动态绑定的,也就是在派生类中可以被覆盖的,这与静态成员函数的定义(在内存中只有一份拷贝,通过类名或对象引用访问静态成员)本身就是相矛盾的。
恋喵大鲤鱼
2018/09/27
1.6K0
今天你学C++了吗?——C++中的多态
具体来说,运行时多态允许我们在完成某个行为(函数)时,传入不同的对象就会完成不同的行为,从而达到多种形态。假设我们正在开发一个图形绘制应用程序,该程序需要支持多种图形对象(如圆形、矩形和三角形)的绘制。我们可以设计一个基类Shape,并在其中定义一个虚函数draw()用于绘制图形。不同的图形对象(圆形、矩形和三角形)将作为Shape的派生类,并在这些派生类中重写draw()函数以实现各自的绘制逻辑。同样地,在动物叫声的模拟中,传入猫对象时发出“喵”的叫声,传入狗对象时发出“汪汪”的叫声,这也是通过多态性来实现的。
用户11352420
2025/03/16
1700
今天你学C++了吗?——C++中的多态
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
函数声明形式 纯虚函数在声明时有其特定的语法形式,如 virtual 函数类型 函数名(参数列表) = 0;。以之前提到的 Base 类中的 virtual void Func() = 0; 为例,virtual 关键字表明这是一个虚函数,而最后的 = 0 则明确指出它是纯虚函数,意味着该函数在当前类(这里是 Base 类)中不提供具体的函数实现(也就是没有函数体),仅预留函数名和参数列表等信息,等待派生类去完善其具体功能。
Rossy Yan
2024/12/24
1260
【C++面向对象——类的多态性与虚函数】计算图像面积(头歌实践教学平台习题)【合集】
深入解析C++中的虚函数和虚继承:实现多态性与继承关系的高级特性
虚函数是在C++中用于实现多态性的一种特殊函数。它通过使用关键字"virtual"进行声明,在基类中定义,可在派生类中进行重写。虚函数允许在运行时根据对象的实际类型来调用相应的函数,而不仅仅根据指针或引用的类型。这使得在继承关系中,通过基类指针或引用调用虚函数时,可以根据实际对象的类型来动态地确定要执行的函数版本,实现多态性的特性。
洁洁
2023/12/12
2.3K0
深入解析C++中的虚函数和虚继承:实现多态性与继承关系的高级特性
C++进阶:详解多态(多态、虚函数、抽象类以及虚函数原理详解)
注意:在重写基类虚函数时,派生类的虚函数在不加virtual关键字时,虽然也可以构成重写(因为继承后基类的虚函数被继承后在派生类依旧保持虚函数属性)但是该种写法不规范,大家还是少用为好。
是Nero哦
2024/03/17
6480
C++进阶:详解多态(多态、虚函数、抽象类以及虚函数原理详解)
再探虚函数
也称为编译期间的多态,编译器在编译期间完成的,编译器根据函数实参的类型(可能会进行隐式类型转换),可推断出要调用那个函数,如果有对应的函数就调用该函数,否则出现编译错误。
看、未来
2021/10/09
9320
再探虚函数
【c++】多态(多态的概念及实现、虚函数重写、纯虚函数和抽象类、虚函数表、多态的实现过程)
本篇文章是继继承之后,博主跟大家介绍面向对象三大特性的最后一个——多态。
ephemerals__
2024/12/25
5390
【c++】多态(多态的概念及实现、虚函数重写、纯虚函数和抽象类、虚函数表、多态的实现过程)
【C++篇】灵动之韵:C++多态之舞,赋予代码生命的艺术
多态,即多种形态,在面向对象编程中意味着可以通过一个基类指针或引用调用不同派生类的成员函数。多态性使得对象可以被作为其基类类型进行操作,而在运行时实际调用的是派生类的实现。
半截诗
2024/10/11
2430
【C++篇】灵动之韵:C++多态之舞,赋予代码生命的艺术
十一、多态
多态是面向对象编程中的一个核心概念,它指的是允许不同类的对象对同一消息作出响应,即同一操作作用于不同的对象,可以有不同的行为。多态问题的引入,可以从以下几个方面进行阐述:
用户11332765
2024/10/28
2070
抽象类纯虚函数与虚析构
纯虚函数,一般是在设计一个基类时使用的,它将接口函数设置为纯虚函数后,只提供子类去继承并实现,以形成多态,除此以外不提供任何其他功能,我们称这种类为抽象类(abstract)。
我与梦想有个约会
2023/10/20
2390
抽象类纯虚函数与虚析构
C++多态与虚函数
SarPro
2024/02/20
2280
C++基础(七).多态(2)
代码示例 shape.cpp #include <iostream> //cout,endl 相关函数的声明 #define PI 3.1415926 //定义一个PI宏 using namespace std; //设定名称空间 class Shape //定义一个Shape的抽象基类 { public: virtual float getArea()=0; //声明一个纯虚函数 Shape(float x=0); //声明一个带默认参值的构造函数 protected: float h
franket
2021/09/15
4460
C++的虚函数与纯虚函数
C++的虚函数是一种特殊的成员函数,用于实现多态性。虚函数允许在基类中声明一个函数,在派生类中根据需要进行重写,并通过基类指针或引用来调用派生类对象的特定实现。
叶茂林
2023/07/30
3130
C++虚函数知识点总结
对应虚函数的类,该类的对象所占内存大小为,数据成员的大小+一个指向虚函数表指针 (4字节)。
半生瓜的blog
2023/05/12
2320
C++虚函数知识点总结
基类派生类多态虚函数?
通常在层次关系的根部有一个基类,其他类则直接或间接的从基类继承而来,这些继承得到的类称为派生类。基类负责定义在层次关系中所有类共同拥有的成员,而每个派生类定义各自特有的成员。
洁洁
2023/10/10
2930
【C++】多态(定义、虚函数、重写、隐藏)
多态的概念:通俗来说,就是多种形态,具体点就是去完成某个行为,当不同的对象去完成时会 产生出不同的状态。
秦jh
2024/07/03
2350
【C++】多态(定义、虚函数、重写、隐藏)
纯虚函数
定义 纯虚函数就是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后面加“=0” 引入原因 方便的使用多态,因此常常在基类中定义虚函数 在很多情况下,基类本身生成对象是不合理的。例如,动物作为一个基类可以派生出老虎、孔雀等子类,蛋动物本身生成对象明显不合常理。 为了解决上述问题,引入了纯虚函数的概念,将函数定义为纯虚函数(virtual ReturnType Function() = 0),则编译器要求在派生类中必须予以重写以实现多
青木
2018/05/28
1.2K0
相关推荐
C++一分钟之-虚函数与抽象类
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验