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

从基类调用虚函数

从基类调用虚函数是指在C++编程中,当一个基类指针或引用指向一个派生类对象时,可以通过基类的指针或引用调用派生类的虚函数。这是C++多态性的一个重要方面,允许程序员编写灵活的代码,可以处理各种类型的对象,而不需要预先知道对象的确切类型。

在C++中,通过在基类中声明一个虚函数,并在派生类中重写该函数来实现这一点。当调用基类指针或引用的虚函数时,程序将根据指针或引用所指向的对象的实际类型来调用正确的派生类函数。

虚函数的使用可以提高代码的可扩展性和可维护性,因为当需要添加新的派生类时,只需要重写虚函数并提供新的实现,而不需要修改现有的代码。

在云计算领域,虚函数的概念可以应用于许多不同的场景,例如在设计和实现云服务时,可以使用虚函数来提供灵活的接口,以便在不同的云服务之间进行切换。此外,虚函数还可以用于实现云服务的自动扩展和自动恢复等功能,以提高云服务的可用性和可靠性。

总之,虚函数是C++中一个非常重要的概念,对于云计算领域的开发工程师来说,理解和掌握虚函数的使用是非常必要的。

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

相关·内容

派生多态函数

通常在层次关系的根部有一个,其他则直接或间接的继承而来,这些继承得到的称为派生负责定义在层次关系中所有共同拥有的成员,而每个派生定义各自特有的成员。...成员函数与继承派生可以继承其的成员, 然而有时候派生必须对其重新定义。派生需要对这些操作提供自己的新定义以覆盖继承而来的旧定义。...当我们使用指针或引用调用函数时,该调用将被动态绑定。...根据引用或指针所绑定的对象类型不同,该调用可能执行的版本,也可能执行某个派生的版木,通过在其成员函数的声明语句之前加上关键字virtual使得该函数执行动态绑定。...成员函数如果没被声明为函数,则其解析过程发生在编译时而非运行时。就会按照实际情况调用。 派生可以继承定义在中的成员,但是派生的成员函数不一定有权访问继承而来的成员。

18120

c++继承 派生 函数

参考链接: C++继承 继承    的关系有组合、继承和代理。继承的本质就是代码复用。子类继承父中的一些东西,父也称为,子类也称为派生。派生继承了除构造函数以外的所有成员。 ...1.调用的构造函数 2.调用派生的构造函数 派生的析构可想而知: 1.调用派生的析构函数 2.调用的析构函数  函数  如下程序:  class Base { public:     Base...中含有函数,那么布局中存在一个函数指针,指向函数表;且其派生中与其同名同参的函数不需要加virtual也是函数。...pb指针调用Show()函数时,发生了动多态。...首先通过指针所指向的对象找到vfptr,再找到vftable,获取到Show函数的入口地址,此时 &Derive::Show中存放的是派生函数入口地址,因此调用的是派生中的Show()函数

1.1K20

C++

如果一个派生有多个直接,而这些直接又有一个共同的,则在最终的派生中会保留该间接共同数据成员的多份同名成员。C++提供的方法,使得在继承间接共同时只保留一份成员。...现在,将A声明为,方法如下: class A//声明基A {…}; class B :virtual public A//声明B是A的公用派生,A是B的 {…}; class...C :virtual public A//声明C是A的公用派生,A是C的 {…}; 注意: 并不是在声明基时声明的,而是在声明派生时,指定继承方式时声明的。...因为一个可以在生成一个派生时作为,而在生成另一个派生时不作为。...可以看到A的构造函数调用了两遍!下面我们把A改成再看看结果。

1.1K20

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

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

7610

C++虚拟继承与

2.如何在派生中只保留一份的拷贝 逻辑上说,一个在职研究生只可能有一个名字和一个身份证号码,所以在一个EGStudent对象中有IDPerson和Name字段的两个拷贝是不合理的,只需要一个拷贝就可以了...(1)当在多条继承路径上有一个公共的,在这些路径中的某几条汇合处,这个公共的就会产生多个实例(或多个副本),若只想保存这个的一个实例,可以将这个公共说明为,就像Student和Employee...(2)被虚拟继承的,叫做实际指的是继承的方式,而非一个,是动词,而非名词。 (3)为了实现虚拟继承,派生对象的大小会增加4。...这个增加的4个字节,是因为当虚拟继承时,无论是单继承还是多继承,派生需要有一个表来记录继承关系,所以此时子类需要多一个表指针,而且只需要一个即可。...(4)虚拟继承中,对象是由最远派生的构造函数通过调用的构造函数进行初始化的,派生的构造函数的成员初始化列表中必须列出对构造函数调用;如果未列出,则表示使用该的缺省构造函数

88920

【Example】C++ 继承 (菱形继承问题)

这时,Base 便成了 Byte 和 Expert 的,达成了继承的方式,Base 在最终的 Blu 中只存在一个,所以不存在命名空间冲突及资源浪费。...并不是“绝对的”,而是“相对的”:在它自身声明、定义的时候无需任何修饰,只是在子类继承时进行 virtual 修饰。...同时,在继承机制当中,是由最终的派生进行初始化的,本身达成了一种 “间接继承” 的关系。 也就意味着最终的派生在构造函数初始化中,要在初始化表中调用的构造函数进行初始化。...这样,就保证了不会被二次初始化。...public: Expert() {}; ~Expert() {}; }; class Blu : public Byte, public Expert { public: // 调用构造函数

93830

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

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

57510

禁止在构造函数调用函数

在构造函数调用函数会导致程序出现莫名其妙的行为,这主要是对象还没有完全构造完成。...这是因为的构造函数调用一个定义在本类中的但是为派生所重写的函数,程序运行的时候会调用派生的版本,程序在运行期的类型是 A 而不是 B。...这么做主要是为了避免在构造函数调用抽象中的方法,防止抛出异常。虽然这么写可以避免这个问题但是还存在一个很大的缺陷,它会造成 str 这个对象在整个生命周期中无法保持恒定的值。...Tip:C# 对象的运行期类型是一开始就定好的,即便是抽象也依然可以调用其中的方法。 小结 在构造函数调用函数会导致代码严重依赖于派生的实现,然后这些实现是无法控制且容易出错的。...也就是说在这种情况下派生必须定义默认构造函数,并且不能定义别的构造函数,这将会给开发人员带来很大的负担。

1.6K20

菱形继承问题及解决方法—继承与(C++)

自带的命令提示工具,到cpp文件存放目录后执行cl /d1 reportSingleClassLayoutSheepTuo test.cpp,其中test.cpp就是文件名,执行结果如下: 很明显羊驼羊和驼两个父中各自继承了一份...m_Age,通过限定作用域的方式无法彻底解决这个问题,这个时候就要使用继承 继承与 具体实现为在羊和驼的继承前加上virtual关键词,Animal称为 代码如下: #include... using namespace std; class Animal // { public: int m_Age; }; class Sheep :virtual public...可以看出羊和驼中的数据只是一个指针,并未继承具体的数据,这个指针指向各自的表,而表中存在一个偏移量,通过这个偏移量再加上首地址可以找到中的数据,所以实际上羊驼只继承了一份数据...(也就是中的那份)。

1.1K40

析构函数? vptr? 指针偏移?多态数组? delete 指针 内存泄漏?崩溃?

2、在遇到通过指针或引用调用函数的语句时,首先根据指针或引用的静态类型来判断所调函数是否属于该class或者它的某个public ,如果 属于再进行调用语句的改写: (*(p->_vptr[slotNum....从而就导致了的析构函数调用了,而派生的析构函数没有调用这个问题发生....Draw(int) 的函数,于是查找是否定义了Draw(int),还是没有,就出错了,出错提示也可以看出来:“IRectangle::Draw”: 函数不接受 1 个参数。...由于的fun不是函数,故p->fun() 调用的是Base::fun()(规则2),而且delete p 还会崩溃,为什么呢?...将析构函数改成函数,fun() 最好也改成函数,只要有一个函数大小就为一个vptr ,此时和派生大小都是4个字节,p也指向派生的首地址,问题解决,参考规则3。

95300

析构函数? vptr? 指针偏移?多态数组? delete 指针 内存泄漏?崩溃?

2、在遇到通过指针或引用调用函数的语句时,首先根据指针或引用的静态类型来判断所调函数是否属于该class或者它的某个public ,如果 属于再进行调用语句的改写: (*(p->_vptr[slotNum....从而就导致了的析构函数调用了,而派生的析构函数没有调用这个问题发生....Draw(int) 的函数,于是查找是否定义了Draw(int),还是没有,就出错了,出错提示也可以看出来:“IRectangle::Draw”: 函数不接受 1 个参数。...由于的fun不是函数,故p->fun() 调用的是Base::fun()(规则2),而且delete p 还会崩溃,为什么呢?...将析构函数改成函数,fun() 最好也改成函数,只要有一个函数大小就为一个vptr ,此时和派生大小都是4个字节,p也指向派生的首地址,问题解决,参考规则3。

1K20

抽象函数析构

函数,一般是在设计一个时使用的,它将接口函数设置为纯函数后,只提供子类去继承并实现,以形成多态,除此以外不提供任何其他功能,我们称这种类为抽象(abstract)。...【纯函数的声明语法】 virtual 函数声明 = 0; 【纯函数的特征】 1、只有声明,没有实现代码。 2、含有纯函数称为抽象(abstract)。不能被实例化,只能被继承。...3、继承抽象的意义就是提供族类的公共接口。 4、子类继承的纯函数,如果未实现,子类仍然为抽象,仍然不能被实例化。 【函数的若干限制】 1、只有的成员函数才能声明为函数。...函数仅适用于有继承关系的对象,所以普通函数不能声明为函数。 2、静态成员函数不能是函数静态成员函数不受对象的捆绑,只有的信息。 3、内联函数不能是函数。...(2, 4, 8); s->draw(); // delete 指针,调用析构函数 delete s; return 0; } 以上代码演示了纯函数的定义,但上面代码存在一个问题,我们先看一下运行的结果

18530

【C++ 语言】面向对象 ( 继承 | 重写 | 子类调用方法 | 静态多态 | 动态多态 | 函数 | 纯函数 )

文章目录 的继承 方法的重写 子类中调用方法 多态 函数 函数示例 纯函数 相关代码 的继承 ---- 1....动态多态 : 在运行时 , 确定函数调用地址 , 这里就用到函数 ; 3 . 函数作用 : 让函数调用的地址 , 在运行时确定调用哪个函数 ; 4....函数解析 : 在对象调用函数方法时 , 系统会查看该对象真正类型是什么类型 , 然后去调用对应类型的方法 ; 对象是使用什么类型的构造函数创建的 , 其真正的类型就是这个类型 , 因此最终调用该类中的函数方法...没有子类 : 函数在子类继承父时才有意义 , 根据类型动态判定该调用哪个方法 , 如果一个没有子类 , 其设置成函数没有意义 , 但也不影响程序运行 ; 函数示例 ---- 函数代码示例解析..." << endl; } }; ③ 调用子类中实现的纯函数 : //在栈内存中创建一个 Child 对象, 并调用其重写的父的方法 Child child; //纯函数测试 parent

1.2K20

Golang面向对象编程之继承&【组合&接口】

[TOC]Golang面向对象编程之继承&【组合&接口】201808相关说明Golang里面没有像C++一样有继承相关的概念,但是我们却可以实现继承相关的用法,这就要用到struct、interface...var RsaSecuritySrv rsaSecurity类似于构造函数的定义,也可以通过new一个对象来使用,二选一。...,很简单,主要就是一个struct里面包含一个匿名的struct,也就是通过匿名组合来实现package mainimport ( "fmt")// 【】//定义一个最基础的structMsgModel...fmt.Println("group.msgType =", group.msgType, "\tgroup.MsgModel.msgType =", group.MsgModel.msgType)}实现的用法...Golang可以interface + struct来实现的用法,必须要实现interface中定义的方法。1,定义一个interface接口MsgModel,包含了一些方法。

1.7K31

构造函数和析构函数可以是函数吗,在里面能调用函数

,一个对象需要调用构造函数完成实例化,这里形成了一个悖论 在意义上,将构造函数声明为函数没有意义,函数主要是实现多态,c++的多态是在运行时构建调用不同函数,而不是根据情况动态调用构造函数...构造函数是不行的,但是析构函数作为函数确实常用的,特别是的析构函数一定要声明为函数。首先既然对象存在,那么函数表肯定存在,所以析构函数作为函数是合理的。...这时候如果是指针指向子类对象,那么删除指针,只会调用的析构函数,因为这时候对象类型是对象,析构函数没有动态绑定,只会调用当前对象类型的析构。...但是如果将析构函数声明为函数,则能成功调用子类的析构函数 #include using namespace std; class Father { public:...//Father f 代码运行后,构造函数调用了父函数,我们本来想要调用子类的函数

1.4K50

从零开始学C++之继承(三):多重继承、继承与

,更好的软件重用 可能会有大量的二义性,多个中可能包含同名变量或函数 多重继承中解决访问歧义的方法: 名::数据成员名(或成员函数(参数表)) 明确指明要访问定义于哪个中的成员...二、继承与 当派生多个派生,而这些又从同一个派生,则在访问此共同中的成员时,将产生二义性,可以采用来解决。...输出可以总结出: 1、的成员是由最远派生的构造函数通过调用的构造函数进行初始化的。...2、在整个继承结构中,直接或间接继承的所有派生,都必须在构造函数的成员初始化表中给出对的构造函数调用。如果未列出,则表示调用的默认构造函数。...3、在建立对象时,只有最远派生的构造函数调用的构造函数,该派生的其他构造函数调用被忽略。

1.1K00
领券