<c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数

这篇具有很好参考价值的文章主要介绍了<c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

<c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数

  • 🚀 个人简介:CSDN「博客新星」TOP 10 , C/C++ 领域新星创作者
  • 💟 作    者:锡兰_CC ❣️
  • 📝 专    栏:从零开始的 c++ 之旅
  • 🌈 若有帮助,还请关注➕点赞➕收藏,不行的话我再努努力💪💪💪

前言

在上一篇文章中,我们介绍了c++中类与对象的继承,继承可以根据一个或多个类来定义一个新的类,减少代码量,使得开发和维护一个应用程序变得更加的容易。本文将介绍c++继承的重要应用 —— 多态。

一、多态

Q:什么是多态?
A:多态是同一个事物在不同场景下的多种形式,具体讲就是去完成某个行为,当不同的对象去完成时会产生出不同的状态。

多态是c++面向对象的三大特性之一,有着动态改变程序的功能,一般分为两类:静态多态和动态多态。

1、静态多态

Q:什么是静态多态?
A:静态多态,又称为编译期多态,它的特点就是函数地址早绑定,即在系统编译期间就可以确定程序将要执行哪个函数。函数重载和运算符重载,都是静态多态。

#include<iostream>
using namespace std;

class base1 {
public:
	void show() {
		cout << "父类中的show函数" << endl;
	}
};
 
class son1 : public base1 {
public:
	void show() {
		cout << "子类son1中的show函数" << endl;
	}
};
 
 
class son2 : public base1 {
public:
	void show() {
		cout << "子类son2中的show函数" << endl;
	}
}; 


int main() {
	base1 *a,*b;
	a = new son1;
	b = new son2;
	a -> show();
	b -> show();
	return 0;
} 

<c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数
在这个例子中,我们在父类base1与两个子类son1 son2中都实现一个show方法,我们分别调用两个子类的show方法,最终输出的都是 父类中的show函数。这说明在静态多态中,在系统编译期间就可以确定程序将要执行哪个函数,函数地址绑定父类中的show函数地址。

2、动态多态

Q:什么是动态多态?
A:动态多态的各种实现方法与静态多态一致,只不过多了一个virtual关键字来修饰,动态多态通过派生类和虚函数在运行时实现。

#include<iostream>
using namespace std;

class base1 {
public:
	virtual void show() {
		cout << "父类中的show函数" << endl;
	}
};
 
class son1 : public base1 {
public:
	void show() {
		cout << "子类son1中的show函数" << endl;
	}
};
 
 
class son2 : public base1 {
public:
	void show() {
		cout << "子类son2中的show函数" << endl;
	}
}; 


int main() {
	base1 *a,*b;
	a = new son1;
	b = new son2;
	a -> show();
	b -> show();
	return 0;
}

<c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数
在这个例子中,我们使用了动态多态,可以成功调用两个子类中的show函数。

二、虚函数与纯虚函数

1、虚函数

Q:什么是虚函数?
A:我们将被virtual修饰过的函数称为虚函数.
从上面案例的运行结果来看,用基类的指针指向一个派生类时,如果调用了虚函数,则会调用派生类对应的虚函数而不是基类本身所拥有的虚函数。

2、纯虚函数

Q:什么是纯虚函数?
A:纯虚函数与虚函数相同,就是一个被virtual修饰过的函数,但是没有函数体,直接等于 0。当一个类中有了纯虚函数,这个类就称为抽象类。抽象类无法实例化对象,子类必须重写抽象类中的纯虚函数,否则也属于抽象类。

三、多态的实现原理

1、虚函数表

Q:什么是虚函数表?
A:虚函数表中存储着虚函数的地址。当派生类重新定义虚函数时,则将该函数的地址添加到虚函数表中。

2、虚函数指针

Q:什么是虚函数指针?
A:当使用虚函数的时候,类空间对象会占用更大的内存空间。编译器会给每一个对象添加一个隐藏变量:指向虚函数表的指针。

注意:无论类的对象中定义了多少个虚函数,虚函数指针只有一个。

3、多态的实现原理

当调用虚函数时,由于派生类对象重写了派生类对应的虚函数表项,基类在调用时会调用派生类的虚函数,从而产生多态。

四、虚析构函数

当通过delete关键字删除有派生类对象的基类指针时,只会调用基类的析构函数,派生类的空间并没有被释放,会造成内存泄漏。为了避免内存泄露,需要使用虚析构函数在删除基类指针时可以调用子类的析构函数释放子类中堆内存,防止内存泄露。

我们来看看下面这个例子:

#include<iostream>
using namespace std;

class base1 {
public:
    base1() {}
    ~base1() { 
		cout<<"delete base1"<<endl; 
	}

    virtual void show() { 
		cout << "show base1" << endl;  
	}
};

class son1 : public base1 {
public:
    son1() {}
    ~son1() { 
		cout << "delete son1" << endl;  
	}

    void show() { 
		cout << "show son1" << endl;  
	}
};

int main() {
    base1 *p = new son1;
    p -> show();
    delete p;
    return 0;
}

<c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数
在这个例子中,我们通过delete关键字删除指针时,没有调用派生类的析构函数。我们试试将基类中的析构函数改为虚析构函数。

#include<iostream>
using namespace std;

class base1 {
public:
    base1() {}
    virtual ~base1() { 
		cout<<"delete base1"<<endl; 
	}

    virtual void show() { 
		cout << "show base1" << endl;  
	}
};

class son1 : public base1 {
public:
    son1() {}
    ~son1() { 
		cout << "delete son1" << endl;  
	}

    void show() { 
		cout << "show son1" << endl;  
	}
};

int main() {
    base1 *p = new son1;
    p -> show();
    delete p;
    return 0;
}

<c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数
可以发现,成功调用了派生类的析构函数,没有造成内存泄漏。

总结一下:

  • 如果父类的析构函数不加上virtual关键字
    当父类的析构函数不为虚析构函数的时候,当子类继承父类,父类的指针指向子类时,delete掉父类的指针,只调动父类的析构函数,而不调动子类的析构函数。
  • 如果父类的析构函数加上virtual关键字
    当父类的析构函数为虚析构函数的时候,当子类继承父类,父类的指针指向子类时,delete掉父类的指针,先调动子类的析构函数,再调动父类的析构函数。

其他:

更多专栏订阅:文章来源地址https://www.toymoban.com/news/detail-417108.html

  • 👍 【开卷数据结构】
  • 💛 【备战蓝桥,冲击省一】
  • 💕   从零开始的 c++ 之旅
  • 💖 【OpenCV • c++】计算机视觉

到了这里,关于<c++>虚函数与多态 | 虚函数与纯虚函数 | 多态的实现原理 | 虚析构函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 虚析构函数相关知识

    注:虚函数的条件: 虚函数能产生地址,存在vftable中 对象必须存在(vfptr-vftable-虚函数地址) 构造函数 virtual+构造函数,错误 构造函数中调用虚函数,不会发生动态绑定(只发生静态绑定) static 静态成员方法也不能加 virtual 首先看如下例子: 输出结果为: Base() Derive() Deri

    2024年02月02日
    浏览(6)
  • Effective C++条款07——为多态基类声明virtual析构函数(构造/析构/赋值运算)

    有许多种做法可以记录时间,因此,设计一个TimeKeeper base class和一些derived classes 作为不同的计时方法,相当合情合理: 许多客户只想在程序中使用时间,不想操心时间如何计算等细节,这时候我们可以设计factory (工厂)函数,返回指针指向一个计时对象。Factory函数会“返回

    2024年02月12日
    浏览(9)
  • 虚函数、纯虚函数、多态

    虚函数、纯虚函数、多态

            在基类的函数前加上virtual,在派生类中重写该函数,运行时将会根据所指对象的实际类型来调用相应的函数,如果对象类型是派生类,就调用派生类的函数,如果对象类型是基类,就调用基类的函数。 注意:如果子类没有重写虚函数,那么子类对象仍然有

    2024年02月09日
    浏览(9)
  • C++:多态的底层实现原理 -- 虚函数表

    C++:多态的底层实现原理 -- 虚函数表

    目录 一. 多态的原理 1.1 虚函数表 1.2 多态的实现原理 1.3 动态绑定与静态绑定 二. 多继承中的虚函数表 2.1 虚函数表的打印 2.2 多继承中虚函数表中的内容存储情况 对于一个含有虚函数的的类,在实例化出来对象以后,对象所存储的内容包含两部分: 类的成员变量。 一

    2023年04月21日
    浏览(9)
  • C++修炼之路之多态---多态的原理(虚函数表)

    C++修炼之路之多态---多态的原理(虚函数表)

    目录 一:多态的原理  1.虚函数表  2.原理分析 3.对于虚表存在哪里的探讨 4.对于是不是所有的虚函数都要存进虚函数表的探讨 二:多继承中的虚函数表 三:常见的问答题  接下来的日子会顺顺利利,万事胜意,生活明朗-----------林辞忧  接上篇的多态的介绍后,接下来介绍

    2024年04月26日
    浏览(11)
  • 【C++】多态的底层原理(虚函数表)

    【C++】多态的底层原理(虚函数表)

    🌏博客主页: 主页 🔖系列专栏: C++ ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 通过观察测试我们发现b对象是8bytes,除了_b成员,还多一个__vfptr放在对象的前面(注意有些平台可能会放到对象的最后面,这个跟平台有关),对象中的这个指针我们叫做虚函

    2024年02月13日
    浏览(11)
  • 【C++】早绑定、析构与多态 | 一道关于多态的选择题记录

    【C++】早绑定、析构与多态 | 一道关于多态的选择题记录

    今天在和群友聊天的时候看到了一道很坑的题目,分享给大家 先来看看题目 请问这个的输出是什么? 答案是E,编译出错! 先来说说这道题目里面涉及到了什么知识点 多态调用; 多态重写函数需要满足什么条件; 类内函数后加 const 的作用; 类内函数后加 override 的作用;

    2024年02月11日
    浏览(9)
  • 【C++】虚函数表 & 多态的原理 & 动态绑定和静态绑定

    【C++】虚函数表 & 多态的原理 & 动态绑定和静态绑定

    梳理虚函数表、多态原理、动静态绑定的知识 目录 一、虚函数表 二、多态的原理 三、动态绑定和静态绑定 在学习多态原理之前,我们需要了解一下虚函数表的概念  我们先一起来看下下面这段代码 通过测试我们发现b对象是8bytes, 除了_b成员,还多一个__vfptr指针放在对象

    2024年02月03日
    浏览(8)
  • C++|29.纯虚函数/接口(待完成)

    C++|29.纯虚函数/接口(待完成)

    纯虚函数是一种特殊的虚函数。 普通的虚函数允许子类的同名函数对其进行重写,同时普通的虚函数本身是可以单独进行使用的。 而纯虚函数是一个空壳,强制要求所派生的类在继承的过程中必要将该虚函数进行实现。 如上图,纯虚函数只需要在virtual后面添加上=0即可。

    2024年01月16日
    浏览(8)
  • 【C++】多态的实现及其底层原理

    【C++】多态的实现及其底层原理

    个人主页:🍝在肯德基吃麻辣烫 我的gitee:gitee仓库 分享一句喜欢的话:热烈的火焰,冰封在最沉默的火山深处。 本文继C++继承之后讲解C++多态。 单单从概念入手不好理解,应该深入理解多态的实现后再回过头来讲解。 现在简单举个例子:我们在购买高铁票时,往往会有成

    2024年02月14日
    浏览(10)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包