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

派生类对基类中虚函数和非虚函数的继承效果

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

43910
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    【C++】多态 ⑧ ( 验证指向 虚函数表 的 vptr 指针 | 对比定义了虚函数的类和没有定义虚函数类的大小 )

    对比 定义了 虚函数 的类 与 没有定义虚函数的类 的大小 , 其它成员都相同 , 定义了虚函数的类多出了 4 字节 , 多出的 4 字节就是 vptr 指针占用的内存空间 ; 一、验证指向 虚函数表...1 个虚函数 ; 如果 没有虚函数 , 就不会生成虚函数表 ; 如果 类 中有 virtual 虚函数 , 则 该类的 每个对象 中 , 都有一个 指向 虚函数表的 vptr 指针 ; 虚函数表 存储...虚函数指针 : " 虚函数表 " 是 存储 " 类成员函数指针 " 的 数据结构 , 是一个 函数指针数组 , 数组中的元素都是函数指针 , 具体存储的都是 指向 类中的虚函数 的指针 ; 如果 子类...中 , 重写了 父类的 virtual 虚函数 , 那么 C++ 编译器会在 子类 虚函数表 中放入该 子类虚函数的 函数指针 ; 如果 C++ 类中存在 virtual 虚函数 , 在创建对象时 ,...Child c; // 将父类指针指向子类对象 p = &c; // 通过父类指针调用子类对象的 fun 函数 p->fun(1); // 打印 Parent 的 大小 cout <<

    37240

    C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址

    C++反汇编第三讲,反汇编中识别虚表指针,以及指向的虚函数地址 讲解之前,了解下什么是虚函数,什么是虚表指针,了解下语法,(也算复习了) 开发知识为了不码字了,找了一篇介绍比较好的,这里我扣过来了...定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。 定义一个函数为纯虚函数,才代表函数没有被实现。...由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被成为“虚”函数。 虚函数只能借助于指针或者引用来达到多态的效果。...熟悉了虚表指针, 通过虚表指针找构造,析构,以及虚表指针指向的虚表找虚函数,那么我们看一下普通成员函数调用和虚函数调用有什么区别....  1.普通成员函数直接调用Call   2.虚函数会通过虚表指针指向的虚表来间接调用.

    1.7K60

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

    在程序修改前,是无法通过基类指针去调用派生类对象中的成员函数的。...虚函数突破了这一限制,在派生类的基类部分中,派生类的虚函数取代了基类原来的虚函数,因此在使基类指针指向派生类对象后,调用虚函数时就调用了派生类的虚函数。...可以看到:当把基类的某个成员函数声明为虚函数后,允许在其派生类中对该函数重新定义,赋予它新的功能,并且可以通过指向基类的指针指向同一类族中不同类的对象,从而调用其中的同名函数。...如果在派生类中没有对基类的虚函数重新定义,则派生类简单地继承其直接基类的虚函数。 定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。...通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。 通过虚函数与指向基类对象的指针变量的配合使用,就能方便地调用同一类族中不同类的同名函数,只要先用基类指针指向即可。

    1.5K80

    必知必会之C++多态机制

    具体来说,多态性允许基类的指针或引用在运行时指向派生类的对象,并且根据对象的实际类型来调用相应的成员函数。 多态性是通过虚函数来实现的。...派生类重写虚函数: 派生类中可以通过重写(覆盖)基类中的虚函数来提供自己的实现。在调用这个虚函数时,会根据对象的实际类型来决定调用哪个版本的函数。...在 main() 函数中,我们创建了 Dog 和 Cat 类的对象,并将基类指针指向这些对象,然后通过基类指针调用虚函数 makeSound()。...方法调用 在 C++ 中,如果父类通过指针或引用调用一个虚函数,而这个虚函数在子类中被重写(override),那么调用的实际方法将取决于指针或引用所指向的对象的类型。这就是多态的体现。...具体来说,如果父类指针或引用指向的是子类对象,那么调用的方法将是子类中重写的版本;如果指针或引用指向的是父类对象,那么调用的方法将是父类中的版本。

    23810

    C++ 多态

    这主要通过继承和虚函数来实现。 继承:允许一个类(子类或派生类)继承另一个类(基类或父类)的属性和方法。子类可以重写基类中的虚函数,从而在运行时表现出不同的行为。...虚函数:在基类中声明为virtual的成员函数。当通过基类指针或引用调用虚函数时,如果指针或引用实际上指向的是派生类对象,那么将调用派生类中重写的虚函数版本。...这意味着当通过基类指针或引用来调用虚函数时,如果指针或引用实际上指向的是派生类对象,那么将调用派生类中重写的虚函数版本。 特点: 基类函数必须是虚函数(用virtual关键字声明)。...多态的原理 多态是通过,根据你提供的ptr判断执行的 当指向的基类的时候,基类通过自己的_vfptr去指向虚函数表,然后指向要对应调用的虚函数,这里指向的都是父类 当指向派生类的时候...,基类的指针对派生类产生了切割,但是这个指针指向的是派生类的_vfptr指向的虚函数表,也就是派生类自己的,派生类通过自己的虚函数表找到覆写的虚函数执行 动态绑定与静态绑定 对不满足多态条件的函数

    13910

    【C++】模板继承多态

    四: 如果派生类中的方法和基类继承来的某个方法,返回值,函数名,参数列表都相同,而且基类的方法是virtual虚函数,那么派生类的这个方法,自动处理成虚函数。...static静态成员方法 (错误) 虚析构函数 (可以) 析构函数调用时,对象是存在的 基类的虚函数是虚函数,派生类的析构函数自动变成虚函数 当基类指针(引用)指向堆上new出来的派生类对象的时候...在类的构造函数当中,调用虚函数,也是静态绑定(构造函数中调用其他 函数(虚)不会发生动态绑定) 如果不是通过指针或者引用变量来调用虚函数,那就是静态绑定。...(引用)调用同名覆盖方法(虚函数),基类指针指向哪个派生类对象,就会调用哪个派生类对象的同名覆盖方法。...多态底层是通过动态绑定来实现的。pbase 指向谁就访问谁的vfptr,从而继续访问谁的vftable,也就调用对应的派生类对象的方法了。

    20510

    C++基础-多态

    这种情况未启用多态机制 如果基类中的 Swim() 是虚函数,那么运行时会根据基类引用(或指针)指向的具体对象,调用对象所属的类中的方法。...若指向派生类对象则调用派生类方法,若指向基类对象则调用基类方法。...这种情况使用了多态机制 使用基类指针或引用指向基类或派生类对象,运行时调用对象所属的类(具有继承层次关系的基类或派生类)中的方法,这就是多态。...换句话说,对于使用 new 在堆内存中实例化的派生类对象,如果将其赋给基类指针,并通过基类指针调用 delete,如果基类析构函数不是虚函数,delete 将按基类析构的方式来析构此指针,如果基类析构函数是虚函数...C++关键字 virtual 被用于实现两个不同的概念,其含义随上下文而异,如下: 在函数声明中, virtual 意味着当基类指针指向派生对象时,通过它可调用派生类的相应函数。

    93520

    十一、多态

    即,需要使用基类类型的指针或引用来指向子类对象,并通过该指针或引用来调用虚函数。 原理:在运行时,程序会根据指针或引用所指向对象的实际类型,在虚函数表中查找并调用相应的函数版本。...多态的意义 提高代码的复用性和可扩展性: 多态允许使用基类类型的指针或引用来引用派生类的对象,这样就可以通过基类指针或引用来调用派生类中的方法,而无需知道具体的派生类类型。...当通过基类指针删除派生类对象时,如果基类的析构函数不是虚的,那么只会调用基类的析构函数,而不会调用派生类的析构函数。...: 虚函数允许在派生类中重写基类的成员函数,并通过基类指针或引用来调用派生类的函数实现,从而实现多态。...调用:当通过对象的指针或引用来调用虚函数时,编译器会首先查找这个指针或引用所指向对象的虚函数表指针,然后通过这个指针找到虚函数表中对应函数的地址,最后调用这个函数。

    26410

    C++虚函数

    虚函数是动态多态性的基础,其调用的方式是动态联编(又称晚期联编,简单解释为只有在程序运行时才决定调用基类的还是子类的,系统会根据基类指针所指向的对象来决定要调用的函数); 非虚函数与其相反,...如果在派生类中没有对基类的虚函数重新定义,派生类简单地继承其直接基类的虚函数。 (3)定义一个指向基类对象的指针变量,并使它指向同一类族中需要调用该函数的对象。...(4)通过该指针变量调用此虚函数,此时调用的就是指针变量指向的对象的同名函数。    ...通过虚函数与指向基类对象的指针变量的配合使用,就能方便地调用同一类的同名函数,只要先用基类指针指向即可。     如果指针不断地指向同一类族中不同类的对象,就能不断地调用这些对象中的同名函数。...(3)应该考虑成员函数的调用是通过对象名还是通过基类指针或引用去访问,如果是通过基类指针或引用去访问,则应当什么为虚函数。 (4)有时在定义虚函数时,并不定义其函数体,即函数体是空的。

    1.2K30

    C++学习——虚函数与纯虚函数

    2、实现这种动态的多态性时,必须使用基类类型的指针变量,并使该 指针指向不同的派生类对象,并通过调用指针所指向的虚函数才能实现 动态的多态性。...虚函数的访问 用基类指针访问与用对象名访问的区别: 1、用基指针访问虚函数时,指向其实际派生类对象重新定义的函数。实 现动态聚束。 2、通过一个对象名访问时,只能静态聚束。...但 可以定义指向抽象类的指针,即指向这种基类的指针。当用这种基类 指针指向其派生类的对象时,必须在派生类中重载纯虚函数,否则会 产生程序的运行错误。...若要访 问类中的私有成员函数,必须通过类中的其它的公有成员函数。 5、当一个成员函数的指针指向一个虚函数,且通过指向对象的基类指针或对象的 引用来访问该成员函数指针时,同样地产生运行时的多态性。...基类为形状类,派生类为矩形类和三角形类,通过基类指针指向不同的派生类对象,调用求面积函数,得到相应的面积结果,实现多态性。

    4.5K20

    【C++篇】虚境探微:多态的流动诗篇,解锁动态的艺术密码

    当程序调用虚函数时,实际的调用流程如下: 通过对象找到虚表指针(vptr)。 根据虚函数的偏移量,从虚表中获取函数指针。 通过函数指针进行实际的函数调用。...多态需求强的场景:当需要通过基类指针或引用调用派生类的不同实现时,动态绑定是必不可少的。虚函数通过虚表机制,可以在运行时调用不同的派生类函数。...当派生类重写了基类的虚函数时,虚表中的基类函数指针会被派生类函数的指针替换。如果派生类定义了新的虚函数,这些新的虚函数指针将会追加到派生类的虚表末尾。...派生类可以通过这个虚表调用基类中的虚函数。 重写虚函数:如果派生类重写了基类的虚函数,则派生类的虚表中相应的函数指针将会被覆盖为派生类的函数实现,重写的虚函数替换基类的虚函数。...3.3.4 调用过程解析 当我们调用 Final 类对象的 func() 方法时,虚拟继承保证调用过程如下: Final 类中的 vptr(虚函数表指针)指向唯一的 Base 类实例的虚函数表。

    19510

    【C++】多态

    ,因为只有基类的指针或引用才能既指向基类对象、又能指向派生类对象。...那么tets中的func()就是通过A*this来调用的(this->func()),父类指针调用虚函数,虚函数又满足相关条件,我们惊奇的发现这里发生了多态。...对象中的这个指针我们叫做虚函数表指针(v代表virtual,f代表function)。这个指针是一个函数指针数组指针,这个指针指向虚函数表,虚函数表中存储虚函数的指针(地址)。...通过下图我们可以看到,满足多态条件后,底层不再是编译时通过调用对象确定函数的地址,而是运行时到指向的对象的虚表中确定对应的虚函数的地址,这样就实现了指针或引用指向基类就调用基类的虚函数,指向派生类就调用派生类对应的虚函数...• 派生类由两部分构成,继承下来的基类和自己的成员,一般情况下,继承下来的基类中有虚函数表指针,自己就不会再生成虚函数表指针,继承自基类的虚函数表指针现在就是整个派生类的虚表指针,指向派生类的虚函数表。

    13410

    【C++进阶】多态,这样学才够清楚

    多态删除:在使用多态时(即基类指针指向派生类对象),如果通过基类指针删除派生类对象,并且基类析构函数没有被声明为虚函数,那么只会调用基类的析构函数,而不会调用派生类的析构函数。...需要注意的是,即使你不需要在派生类的析构函数中执行任何特定的清理工作,如果你打算通过基类指针来删除派生类对象,并且想要确保派生类对象中的资源被正确释放,你也应该将基类的析构函数声明为虚函数。...这样做可以确保当通过基类指针删除派生类对象时,派生类的析构函数也会被调用。...当通过基类指针或引用调用虚函数时,程序会首先查找该指针所指向的虚函数表,然后根据表中存储的地址来调用相应的函数。 | 最后有一个问题:虚函数存在哪里?虚表存在哪里?...当通过基类指针或引用调用虚函数时,会根据指针或引用实际指向的对象的类型来调用相应的函数版本,这称为动态绑定。 2.3 动态绑定和静态绑定 静态绑定,也称为早期绑定,指的是函数调用在编译时期就已经确定。

    13910

    【C++】多态(定义、虚函数、重写、隐藏)

    继承中要构成多态还有两个条件: 必须通过基类的指针或者引用调用虚函数 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写 如果是通过基类的指针调用虚函数,要如下图所示使用: 虚函数 虚函数...即基类虚函数返回基类对象的指针或者引用,派生类虚函数返回派生类对象的指针或者引用时,称为协变。 返回值类型必须是指针或者引用,且具有父子关系(即继承)。...虽然Car不能实例化对象,但是可以用它的指针指向子类,然后调用。 接口继承和实现继承 普通函数的继承是一种实现继承,派生类继承了基类函数,可以使用函数,继承的是函数的实 现。...派生类的虚表生成:1.先将基类中的虚表内容拷贝一份到派生类虚表中 2.如果派生类重写了基类中某个虚函数,用派生类自己的虚函数覆盖虚表中基类的虚函数 3.派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类虚表的最后...基类引用引用子类对象后,通过基类对象调用f2时,调用的是子类的f2(错) 解释:通过对象调用时编译期间就直接确定调用那个函数了,不会通过虚表以多态方式调用 3 虽然进行了强转,pa指向的依旧是是B

    25410

    剖析多态的原理及实现

    必须通过基类的指针或引用来调用虚函数。...多态的实现 基本条件 通过基类的指针或引用调用虚函数:多态的前提是通过基类的指针或引用来访问派生类对象。...只有基类的指针或引用才能够指向不同的派生类对象,并且根据派生类对象的实际类型,决定具体调用哪个函数。...如果基类析构函数不是虚函数,那么通过基类指针删除派生类对象时,只会调用基类的析构函数,派生类的析构函数不会被调用,导致资源无法释放。...当通过基类指针调用show函数时,具体调用哪个函数取决于实际的对象类型。 隐藏(Hiding) 隐藏是指在派生类中定义了一个与基类同名但非虚的函数,此时基类的同名函数会被隐藏。

    27110

    【C++ 多态】—— 礼器九鼎,釉下乾坤,多态中的 “风水寻龙诀“

    它允许通过基类指针或引用调用派生类的重写函数,是面向对象编程中实现“一个接口,多种实现”的关键工具。 虚函数的概念: 虚函数 是用 virtual 关键字声明的成员函数,用于实现 运行时多态。...后果:派生类函数与基类函数是独立的,无法通过基类指针/引用调用多态。...当基类指针指向派生类对象时,若基类的析构函数是虚函数,删除该指针会触发动态绑定,确保调用实际对象类型的析构函数。...如果基类的析构函数没有被定义为虚函数,那么在析构时就不会触发动态绑定,实际上会通过静态绑定直接指向该指针的类型对象,即基类,从而只调用基类的析构函数,释放基类的资源,导致派生类的析构函数无法被调用,造成内存泄漏等问题...,允许基类指针或引用在运行时根据实际对象类型调用对应的派生类方法:编译器为每个含虚函数的类生成虚函数表(存储函数地址),对象内置虚表指针(vptr)指向所属类的虚表,当通过基类指针调用虚函数时,程序通过

    11200

    C++ 多态、虚函数、纯虚函数《Rice C++ 学习开发》

    静态多态:调用函数被编译器设置为基类中的版本,函数调用在程序执行前就决定了好了,这就是所谓的静态多态,或静态链接。 动态多态:派生类对象的地址可以赋值给基类指针。...对于通过基类指针调用基类和派生类中都有的同名、同参数表的虚函数的语句,编译时并不确定要执行的是基类还是派生类的虚函数;而当程序运行到该语句时,如果基类指针指向的是一个基类对象,则基类的虚函数被调用,如果基类指针指向的是一个派生类对象...动态多态: 静态多态变成动态多态,需要稍微修改一下代码,通过虚函数的方法来实现动态链接。在函数前添加virtual。虚函数是一种在基类定义为virtual的函数,并在一个或多个派生类中再定义的函数。...: 您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。...,如果派生类重写了虚函数,则调用子类的函数,否则调用基类的函数。

    39520

    深入浅出C++虚函数的vptr与vtable

    此表中的每个条目只是一个函数指针,指向该类可访问的最派生函数。 其次,编译器还会添加一个隐藏指向基类的指针,我们称之为vptr。vptr在创建类实例时自动设置,以便指向该类的虚拟表。...(); cout基类引用指向派生类实例"<<endl; pp.fun1(); cout基类指针指向派生类实例并调用虚函数"<<endl; pt->fun1(...Base::fun1() 基类引用指向派生类实例 Base::fun1() 基类指针指向派生类实例并调用虚函数 Derived::fun1() 基类引用指向基类实例并调用虚函数 Derived::fun1...简单的说,通过virtual函数,指向子类的基类指针可以调用子类的函数。...例如,上述通过基类指针指向派生类实例,并调用虚函数,将上述代码简化为: Base *pt = new Derived(); // 基类指针指向派生类实例 cout基类指针指向派生类实例并调用虚函数

    4.5K30
    领券