首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

从基类访问派生的虚函数,这是很好的实践吗?

从基类访问派生的虚函数是一种常见的实践,它可以实现多态性和动态绑定的特性。通过基类指针或引用调用虚函数时,会根据实际对象的类型来确定调用的是基类还是派生类的虚函数,从而实现了运行时的多态性。

这种实践的优势在于:

  1. 灵活性:通过基类指针或引用调用虚函数,可以根据实际对象的类型来动态选择调用的函数,从而实现灵活的对象行为。
  2. 扩展性:当需要添加新的派生类时,只需要继承基类并实现相应的虚函数即可,不需要修改基类的代码,从而实现了代码的扩展性。
  3. 可维护性:通过使用虚函数,可以将相关的代码组织在一起,提高代码的可读性和可维护性。

这种实践在以下场景中特别适用:

  1. 多态性需求:当需要处理一组对象,这些对象可能属于不同的派生类,但又具有相同的基类接口时,可以使用基类指针或引用调用虚函数来实现多态性。
  2. 扩展性需求:当需要在现有的类层次结构中添加新的派生类,并且这些派生类需要具有与基类相同的接口时,可以使用虚函数来实现扩展性。

腾讯云提供了一系列与云计算相关的产品,其中与虚拟化和多态性相关的产品包括云服务器(CVM)和容器服务(TKE)。您可以通过以下链接了解更多关于腾讯云的产品信息:

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

派生函数和非虚函数继承效果

函数作用,主要是为了让父指针可以调用子类函数,这种是在运行时才决定调用哪个函数 1、函数:   C++函数主要作用是“运行时多态”,父中提供函数实现,为子类提供默认函数实现。...子类可以重写父函数实现子类特殊化。 2、纯函数:   C++中包含纯函数,被称为是“抽象”。抽象不能使用new出对象,只有实现了这个纯函数子类才能new出对象。   ...C++中函数更像是“只提供申明,没有实现”,是对子类约束,是“接口继承”。   C++中函数也是一种“运行时多态”。...3、普通函数:   普通函数是静态编译,没有运行时多态,只会根据指针或引用“字面值”对象,调用自己普通函数。   普通函数是父为子类提供“强制实现”。   ...因此,在继承关系中,子类不应该重写父普通函数,因为函数调用至于对象字面值有关。 参考链接

3210

C++中派生成员访问形式

C++中派生成员访问形式主要有以下两种: 1、内部访问:由派生中新增成员对继承来成员访问。 2、对象访问:在派生外部,通过派生对象对继承来成员访问。...今天给大家介绍在3中继承方式下,派生成员访问规则。...private成员在私有派生中是不可直接访问,所以无论是派生成员还是通过派生对象,都无法直接访问继承来private成员,但是可以通过提供public成员函数间接访问。...private成员在私有派生中是不可直接访问,所以无论是派生成员还是派生对象,都无法直接访问继承来private成员,但是可以通过提供public成员函数直接访问它们。...private成员在私有派生中是不可直接访问,所以无论是派生成员还是通过派生对象,都无法直接访问private成员。

2.3K70

C++编程经验(2):为析构函数必要性

这个要提一下,如果记不住就记住:如果不做析构函数,会有内存泄漏 解释 定义一个指针p,在delete p时,如果析构函数函数,这时只会看p所赋值对象,如果p赋值对象是派生对象,...就会调用派生析构函数;如果p赋值对象是对象,就会调用析构函数,这样就不会造成内存泄露。...如果析构函数不是函数,在delete p时,调用析构函数时,只会看指针数据类型,而不会去看赋值对象,这样就会造成内存泄露。 多少学点设计模式就清楚了。...接下来是一个子类 class Inherit :public Base{ //此处省去,一切从简 }; //重点看调用 int main() { Base *p = new Inherit; //这种方式调用...,这时候有没有析构就不一样了 delete p; Base *q = new Base; delete q; return 0; }

56010

从零开始学C++之继承(二):继承与构造函数派生转换

一、不能自动继承成员函数 构造函数(包括拷贝构造函数) 析构函数 =运算符 二、继承与构造函数 构造函数不被继承,派生中需要声明自己构造函数。...声明构造函数时,只需要对本类中新增成员进行初始化,对继承来成员初始化调用构造函数完成(如果没有给出则默认调用默认构造函数)。...输出可以看出: 派生对象构造次序: 先调用对象成员构造函数,接着是构造函数,然后是派生对象成员构造函数,最后是派生自身构造函数。...初始化列表参数多个且其中有调用构造函数时,先执行构造函数最远开始,如果多重继承则按继承顺序);其他对象成员若不止一个,则按定义顺序构造,与初始化列表顺序无关。...向下转型不安全,没有自动转换机制 // 语法上来演示对象可以转化为派生对象,但是没有意义 1、转换构造函数: Manager(const Employee& other) : Employee

1.5K00

C++基础-多态

编程实践:对于将被派生覆盖方法,务必将其声明为函数,以使其支持多态。 2. 析构函数 析构函数与普通函数机制并无不同。...编程实践:务必要将析构函数声明为函数,以避免派生实例未被妥善销毁情况发生。 3....// 访问派生覆盖函数(覆盖普通函数) d.B::func3(); // 访问函数 d.B::func4(); // 访问函数 d.B...可见使用继承可以解决多继承时菱形问题,确保 在继承层次结构中,继承多个同一个派生而来时,如果这些没有采用继承,将导致二义性。...• 派生中被声明为 override 函数是否是中对应函数覆盖?确保没有有手误写错。 编程实践:在派生中声明要覆盖函数函数时,务必使用关键字 override 7.

83220

再探函数

2、纯函数是在中声明函数,它在中没有定义,但要求任何派生都要定义自己实现方法。在中实现纯函数方法是在函数原型后加"=0" 3、声明了纯函数是一个抽象。...(这句话刚开始还真没反应过来,也是啊,都不能初始化对象了,还怎么去调用方法啊) ---- Q3:抽象派生对象可以调用方法?...只有在析构函数定义为函数时,调用操作符delete销毁指向对象指针时,才能准确调用派生析构函数该级向上按序调用函数),才能准确销毁数据。...所以在调用析构函数时,派生对象数据成员已经销毁,这个时候再调用子类函数没有任何意义。 ---- Q8:静态函数能定义为函数?...每一个有函数(或有函数派生)都有一个函数表,该类任何对象中都放着该函数指针(可以认为这是由编译器自动添加到构造函数指令完成)。

85220

调用及其调用具体形式

这是函数被“实调用”另一个例子。由于概念上说,在一个对象构造函数运行完毕之前,这个对象还没有完全诞生,所以在构造函数中调用函数,实际上都是实调用。...析构时,在销毁一个对象时,先调用该类所属析构函数,然后再调用其析构函数。所以,在调用析构函数时,派生已经被析构了,派生数据成员已经失效,无法动态调用派生函数。...3.调用常见形式 设立函数初衷就是想在设计时候,对该派生实施一定程度控制。笼统说,就是“通过访问派生成员”。...因此,调用最常见形式是:通过指向指针或引用来访问派生对象函数。这种情况较为常见。...不常见形式: 不过由于调用是通过查询函数表来实现,而拥有函数对象都可以访问道所属函数表,所以,一个不常见做法是通过指向派生对象指针或引用调用对象函数,考察如下代码。

38710

c++和继承面试点25连问

,先调用构造函数,再调用派生构造函数派生对象销毁时,先调用派生析构函数,再调用析构函数。...运行时多态简单来讲就是:使用指针或者引用指向一个派生对象,在非虚继承情况下,派生直接继承表指针,然后使用派生函数去覆盖函数,这样派生对象通过表指针访问函数就是派生函数了...因为销毁时候直接销毁指针,此时编译器只知道调用析构,并不会主动去调用派生析构函数,所以析构函数需为析构函数,这样运行时程序才会去调用派生析构函数,其实这就相当于析构函数多态,...这是因为成员函数实现机制,上题说了,成员函数跟某个对象无关,实际上它被编译后,我们可以把它理解为一个全局性函数汇编角度看,print函数被编译后真正函数名是_ZN7CPeople5printEv...同样,这段代码里面的CPeople就是抽象了,某个不论是自己定义了纯函数,还是其他继承了纯函数但却并没有实现,都可以称为抽象,所谓抽象,其实就是具体反义词,比方说这里只给了一个接口

90410

C++核心准则C.35:析构函数要么是公开函数,要么是保护非虚函数

为了避免无定义行为。如果析构函数是公有的,那么调用侧代码就会尝试使用指针销毁派生对象,在析构函数为非虚函数时其结果时没有定义。...如果析构函数时保护,那么调用侧代码就无法通过类型指针销毁派生对象,这是析构函数就没有必要一定是函数。析构函数是保护而不是私有的,这样派生析构函数才能调用它。...函数定义了派生接口,它可以在不关注派生情况下使用。如果接口允许对象,那么这个销毁过程应该是安全。...我们可以想象一种需要保护函数析构函数情况:当希望允许派生对象(只有这个类型)通过指针销毁另外一个对象(不是它自己)时。但是我们还没有在实际开发中遇到这种情况。...拥有函数函数要么是公开函数,要么是保护非虚函数。 译者注:拥有函数一般就意味着它有派生

1K20

总结继承和多态一些问题

不行,因为对象中函数表指针是在构造函数初始化列表阶段才初始化。 4.区分切片和派生生成 先来说派生生成步骤: ①先是继承了表,是把表拷贝下来了。...因此,简单总结就是:派生对象赋值给对象,切片会把派生中包含成员变量值拷贝过去,但是派生表不会给拷贝过去,则函数中这个对象表是,所以无法实现多态。...而指针或者引用是直接指向派生对象,不会进行拷贝赋值,这样函数表是派生函数表,故能实现多态。 5.inline函数可以是函数?...不能,因为静态成员函数没有this指针,使用类型::成员函数调用方式无法访问函数表,所以静态成员函数无法放进函数表。 7.析构函数可以函数析构函数最好是函数。...因为有时候我们难免会用指针或引用指向派生对象,析构函数函数的话,可以准确地调用派生析构函数。 8.对象访问普通函数快还是函数更快? 首先如果是普通对象,是一样快

43420

C++调用及其调用具体形式

这是函数被“实调用”另一个例子。由于概念上说,在一个对象构造函数运行完毕之前,这个对象还没有完全诞生,所以在构造函数中调用函数,实际上都是实调用。...析构时,在销毁一个对象时,先调用该类所属析构函数,然后再调用其析构函数。所以,在调用析构函数时,派生已经被析构了,派生数据成员已经失效,无法动态调用派生函数。...3.调用常见形式 设立函数初衷就是想在设计时候,对该派生实施一定程度控制。笼统说,就是“通过访问派生成员”。...因此,调用最常见形式是通过指向指针或引用来访问派生对象函数。这种情况较为常见。...不过由于调用是通过查询函数表来实现,而拥有函数对象都可以访问到所属函数表,所以,一个不常见做法是通过指向派生对象指针或引用调用对象函数,考察如下代码。

47030

【C++】多态

我们可以通过对比地址方式来确定位置,代码运行结果就可以看出,表地址和代码段地址较为相近,所以表位置极大可能性就是在代码段,另一方面去理解的话,函数本质不就是成员函数?...从下面的打印结果就可以验证派生函数放在第一张表里面,其实我们内存窗口也可以看出来第一张表里面放着派生自己函数,这些都没有什么问题。...重定义要求较为宽松,指的是在继承体系中,派生中出现同名函数情况,只要函数名相同就构成隐藏,在调用时,若不指定域,默认访问同名函数派生域,编译器就近原则,找近对于编译器来说比较轻松嘛...内存角度和语法角度来看,菱形继承分别带来了数据冗余和二义性问题,虚拟继承能够解决菱形继承原理即通过方式进行解决,内存中只存一份成员,腰部派生访问时通过自身成员模型中表来进行访问...,表中存放着腰部类到成员偏移量,如果腰部类想要访问成员时,则通过自身成员变量中表来进行成员访问,这便解决了数据冗余问题,在访问冗余数据时,也不会出现二义性了,无论你怎么访问

51120

【C++】三大特性之多态

}; 3.函数重写(覆盖) 派生中有一个跟完全相同函数(即派生函数函数返回值类型、函数名字、参数列表完全相同) ,称子类函数重写了函数。...协变(派生函数返回值类型不同) 派生重写函数时,与函数返回值类型不同。即函数返回对象指 针或者引用,派生函数返回派生对象指针或者引用时,称为协变。...总结一下派生表生成: a.先将表内容拷贝一份到派生表中 b.如果派生重写了中某个函数,用派生自己函数覆盖表中函数 c.派生自己新增加函数按其在派生声明次序增加到派生最后...答:不能,因为静态成员函数没有this指针,使用类型::成员函数 调用方式无法访问函数表,所以静态成员函数无法放进函数表。 3. 构造函数可以是函数?...答:可以,并且最好把析 构函数定义成函数。 5. 对象访问普通函数快还是函数更快?答:首先如果是普通对象,是一样快

70750

C++:继承与派生

3、继承成员访问方式变化 总结: 1、private成员在派生中无论以什么方式继承都是不可见。...2、private成员在派生中是不能被访问,如果成员不想在外直接被访问,但需要在派生中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现。...派生构造函数必须调用构造函数初始化那一部分成员。如果没有默认构造函数,则必须在派生构造函数初始化列表阶段显示调用。 2....4、派生析构函数会在被调用完成后自动调用析构函数清理成员。因为这样才能 保证派生对象先清理派生成员再清理成员顺序。 5....这是为了后面的函数表做准备,用来存表找到函数偏移量(菱形继承多态)。在多态那一环节会去验证。 八、继承总结和反思 1. 很多人说C++语法复杂,其实多继承就是一个体现。

10710

C++入门到精通(第九篇) :多态

函数返回对象指针或者引 用,派生函数返回派生对象指针或者引用时,称为协变。...(派生析构函数名字不同) 如果析构函数函数,此时派生析构函数只要定义,无论是否加virtual关键字,都与 析构函数构成重写,虽然派生析构函数名字不同。...总结一下派生表生成:a.先将表内容拷贝一份到派生表中 b.如果派生重写了 中某个函数,用派生自己函数覆盖表中函数 c.派生自己新增加函数按其在 派生声明次序增加到派生最后...答:不能,因为静态成员函数没有this指针,使用类型::成员函数调用方式 无法访问函数表,所以静态成员函数无法放进函数表。 构造函数可以是函数?...当指针指向new出来派生对象时候,需要使用指针进行释放对象,此时需要析构函数函数,保证指针指向对象成功释放 对象访问普通函数快还是函数更快?

43830

C++之函数作用和使用方法

C++中函数就是用来解决这个问题函数作用是允许在派生中重新定义与类同名函数,并且可以通过指针或引用来访问派生同名函数。 请分析例12.2。...函数突破了这一限制,在派生部分中,派生函数取代了原来函数,因此在使指针指向派生对象后,调用函数时就调用了派生函数。...但是,继承来某些成员函数不完全适应派生需要,例如在例12.2中,display函数只输出数据,而派生display函数需要输出派生数据。...利用函数很好地解决了这个问题。...如果在派生中没有对函数重新定义,则派生简单地继承其直接函数。 定义一个指向对象指针变量,并使它指向同一族中需要调用该函数对象。

1.4K80

浅析C++内存布局

C内存布局如下: 可见,派生C中依其继承顺序,存放了各个subobject及各自vptr,然后才是Class C自己数据成员。...同时也可以想到,随着base class数量增多,派生里也会首先顺序存放各个subobject。而派生中也会记录其到各个base subobjectoffset。...菱形继承不仅浪费存储空间,而且造成了数据访问二义性。虚拟继承可以很好地解决这个问题。 同样以3.2.中继承关系为例,不过这次我们B和C对A继承都加上了关键字virtual。...A内存布局同1.2。B和C内存布局如2.2?是?不是!如下图: 可以看到,class B中有两个指针:第一个指向B自己表,第二个指向A表。...而且,布局上看,class B部分要放在前面,A部分放在后面。在class B中A成分相对内存起始处偏移offset等于class B大小(8字节)。C内存布局和B类似。

46010

闭关多日,整理一份C++中那些重要又容易忽视细节

运算符重载 面试题:C++自动提供成员函数 为什么需要析构函数?...---- 为什么需要析构函数?...,这时只会看p所赋值对象,如果p赋值对象是派生对象,就会调用派生析构函数(毫无疑问,在这之前也会先调用构造函数,在调用派生构造函数,然后调用派生析构函数析构函数,所谓先构造后释放...这种数组称为函数表(virtual function table, vtbl)。 函数表中存储了为对象进行声明函数地址。 例如,对象包含一个指针,该指针指向中所有函数地址表。...派生对象包含一个指向独立地址表指针。如果派生提供了函数新定义,该函数表将保存新函数地址;如果派生没有重新定义函数,该vtbl将保存函数原始版本地址。

57510

C++一分钟之-继承与多态概念

继承:站在巨人肩膀上概念继承允许我们定义一个派生另一个)那里继承属性和方法。这样做可以复用现有代码,同时在新中添加或修改功能,实现代码重用和扩展。...常见问题与易错点访问权限:派生可能无法访问私有成员,导致误解。记住,只有公有和保护成员才能被继承。构造函数与析构函数构造函数和析构函数不会自动被调用,需要显式调用或使用初始化列表。...在C++中,主要通过函数实现多态,使得派生可以根据自身情况重写函数。...常见问题与易错点忘记使用virtual关键字:如果函数没有声明为函数派生即使重写了该函数,也无法实现动态绑定。切片问题:当将派生对象赋值给对象时,派生特有的部分会被“切片”掉。...空指针调用函数:对空指针调用函数会导致运行时错误。如何避免确保需要被重写函数声明为函数。使用引用或指针处理派生关系,避免切片问题。在调用函数前检查指针是否为空。

5610

每日一问06 构造函数可以是函数

技术分类:开发语言 前置知识:函数工作原理 推荐阅读 :[侯捷]C++内存管理--平地到万丈高楼 https://www.bilibili.com/video/BV1Kb411B7N8 思路 构造函数可以是函数...我误区 根本说不清楚:直接回答vptr构造 不相关, 不懂 构造函数无法通过指针访问原理,new 如何调用构造函数申请用法。...根本说不清楚:必须创建好了,才能用,不懂 抽象和具体关系.接口不属于具体一个 析构函数可以是函数,为什么 参考思路: 可以是 析构函数 执行顺序是 派生 如果析构函数不被声明成函数,则编译器实施静态绑定...,在删除指向派生指针时,只会调用析构函数而不调用派生析构函数,这样就会造成派生对象析构不完全。...如果声明了,触发 派生 正确析构顺序。

68630
领券