前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >抽象类为什么不能被实例化?

抽象类为什么不能被实例化?

作者头像
用户6557940
发布2023-09-06 12:50:13
3630
发布2023-09-06 12:50:13
举报
文章被收录于专栏:Jungle笔记Jungle笔记

首先,语法上,抽象类不能被实例化,这是语法规定。强制实例化一个抽象类的代码,编译器会报错。

其次,从继承和多态思想的角度而言,抽象基类的目的是建立一个公共接口,建立公共接口的唯一原因是它能对于每个不同的子类有不同的表示。它建立一个基本的格式,用来确定什么是对于所有派生类是公共的——除此之外,别无用途。抽象基类仅仅表示接口,不表示特例实现,因此,实例化一个抽象类对象,总是没有意义的。

第三,从编译器设计的实现上来看,如果想要禁止用户实例化抽象类,可以在抽象类的所有虚函数里,打印出错的信息,以提示用户不能实例化抽象基类。但是这种方法只有到运行时才能获得出错信息,并且要求程序员进行可靠且详尽的测试,并不能禁止程序员实例化抽象基类。最好是在编译时就能发现这个问题。

实现上,通过在虚函数结尾处加上"=0"来声明纯虚函数:

代码语言:javascript
复制
virtual void func() = 0;

虚函数与多态的原理在于,带有虚函数的类及其派生类,其对象内部会有一个指向VTABLE的指针,即vptr。VTABLE,即虚表,其中会填写好每个虚函数的地址:如果派生类覆写(override)了某个虚函数,那么该虚函数的所占据的表项将填为派生类覆写的虚函数的地址。否则,该表项填写基类该虚函数的地址。通过这样的机制,可以保证以指针或引用方式(即地址)访问派生类对象时,总是会通过vptr所指向的虚表中某个特定索引位置上的函数地址,调用实际指针或引用所指的派生类对象定义的虚函数实现。

其中,”填写“这个动作,实际上是编译器来完成,当构建派生类对象时(即构造函数),编译器会在VTABLE中放置特定类的虚函数的地址。

如果将基类的虚函数声明为纯虚函数,即:

代码语言:javascript
复制
virtual void func() = 0;

这样做,等于告诉编译器,在VTABLE中为函数保留一个位置,但在这个特定位置中不放地址(函数地址)。因此,只要有一个函数在类中被声明为纯虚函数,则VTABLE就是不完全的

如果一个类的VTABLE是不完全的,当某人试图创建这个类的对象时,编译器做什么呢?它不能安全地创建一个纯抽象类的对象。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-06-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Jungle笔记 微信公众号,前往查看

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

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档