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

C++】多态 ⑤ ( 虚函数 | 虚函数语法 | 虚函数意义 | 父指针指向子类对象情况下父和子类使用 virtual 虚函数 | 代码示例 )

A 构造函数 , 然后调用 B 构造函数 , 最后调用 C 构造函数 ; 参考 【C++】继承 ⑧ ( 继承 + 组合 模式对象 构造函数函数 调用规则 ) 博客中 , 构造函数...子类 中覆盖 父 函数 ; 场景说明 : A , B 继承 A ; 声明一个 A 类型 指针变量 , 为其赋值 B 类型对象地址 , 当需要释放该指针变量时 , 使用...; 当使用 父 指针指向一个 子类 对象时 , 如果要通过 delete 释放该指针指向对象 , 如果是正常函数 , 没有 使用 virtual 定义虚函数 , 则只会调用 父 函数..., 只有 函数是 虚函数 时 , 子类 函数才必须是虚函数 ; 如果 父 函数 不是 虚函数 , 则 子类 函数 可以是 普通 非虚函数 ; 二、代码示例 -...在下面的代码中 , 将 父 和 子类 函数 , 都使用 virtual 关键字修饰 ; 声明 子类指针 指向 子类对象 , 释放 子类指针 时 先调用 子类函数 , 再调用父函数 ;

20720

C++构造函数函数

C++中每个都有其构造与函数,它们负责对象创建和对象清理和回收,即使我们不写这两个,编译器也会默认为我们提供这些构造函数。...下面仍然是通过反汇编方式来说明C++中构造和函数是如何工作。...编译器是否真的会默认提供构造与函数 一般讲解C++书籍中都会提及到当我们不为提供任何构造与函数时编译器会默认提供这样六种成员函数:不带参构造,拷贝构造,“=”重载函数函数,以及带const...由于默认拷贝构造是进行简单内存拷贝,所以当成员中有指针变量时尽量自己定义拷贝构造,进行深拷贝,否则在以后进行时会崩溃。...,但是接着执行函数函数中定义对象,接受返回值得这块内存一直等到它所在语句块结束才调用 如果不要这个返回值时又如何呢,下面的代码说明了这个问题 int main() {

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

C++核心准则​讨论:将函数设为公共和虚拟,或受保护和非虚拟

函数应该是虚函数吗?也就是说,是否应该允许通过指向指针进行销毁?如果是,则base函数必须是公共才能被调用,否则虚拟调用它会导致未定义行为。...如果Base函数是公共和非虚拟(默认值),则可能会意外地实际指向派生对象指针上调用它,在这种情况下,尝试删除行为是不确定。...如第39项所述,对于普通成员函数,选择之间是允许以非虚拟方式(通过指向Base指针)调用它(但如果它调用虚拟函数(例如在NVI或模板方法模式中),则可能具有虚拟行为) ),实际还是根本没有。...可以看作只是另一种操作,尽管具有使非虚调用变得危险或错误特殊语义。因此,对于函数,选择是根据是否允许通过指向Base指针实际上调用它。“非虚”不是一种选择。...因此,如果可以调用(即是公共函数,则它是虚拟,否则是非虚拟

1.1K20

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; }

55810

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

C.35: A base class destructor should be either public and virtual, or protected and nonvirtual 函数要么是公开函数...为了避免无定义行为。如果函数是公有的,那么调用侧代码就会尝试使用指针销毁派生对象,函数为非虚函数时其结果时没有定义。...如果函数时保护,那么调用侧代码就无法通过类型指针销毁派生对象,这是函数就没有必要一定是虚函数函数是保护而不是私有的,这样派生函数才能调用它。...通常,设计者不会知道函数中应该执行什么样动作。...我们可以想象一种需要保护函数函数情况:当希望允许派生对象(只有这个类型)通过指针销毁另外一个对象(不是它自己)时。但是我们还没有实际开发中遇到这种情况。

1K20

工作中常见几种内存泄漏场景汇总

3、函数引发内存泄露 C++中,如果子类对象是通过指针进行删除,如果函数不是虚拟,那么子类函数可能不会被调用,从而导致派生资源没有被释放,进而产生内存泄漏。...函数中定义了一个指针,并指向其子类对象,随后对指针进行释放,本意是想通过对指针释放同时也调用子类函数释放子类资源。...这是因为,中并没有定义函数,在这种情况下,编译器会为我们默认生成一个函数,但还不够智能,生成函数不是虚拟,这样在对指针进行时就不能调用子类函数释放资源。...如果想要达到我们想要效果,只需将函数定义成虚即可。修改后运行结果如图所示: 可见,子类中资源得到正常释放。...但是这样做就破坏了delete工作原理,delete删除对象时,先调用对象函数,再delete指针对象,上面的代码将pBase转换成void*后,delete获取不到对象类型就不能正确调用对象函数

91220

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

,为什么 和普通函数对比 首先,C++不支持虚拟构造函数。...我误区 根本说不清楚:直接回答vptr构造 不相关, 不懂 构造函数无法通过指针访问原理,new 如何调用构造函数申请用法。...根本说不清楚:必须创建好了,才能用,不懂 抽象和具体关系.接口不属于具体一个 函数可以是虚函数吗,为什么 参考思路: 可以是 函数 执行顺序是 派生 如果函数不被声明成虚函数,则编译器实施静态绑定...,删除指向派生指针时,只会调用函数而不调用派生函数,这样就会造成派生对象不完全。...如果声明了,触发 派生 正确顺序。

68330

C++核心准则C.127:包含虚函数应该有虚函数或保护函数

C.127: A class with a virtual function should have a virtual or protected destructor C.127:包含虚函数应该有虚函数或保护函数‍...包含虚函数通常(大多数情况下)通过指向指针使用。通常,最后一个使用者必须通过指向指针调用delete操作,通常是指向智能指针,因此函数应该是公开函数。...稍微特殊一些情况是:如果不希望支持通过指向指针销毁对象,函数应该是保护非虚函数。参见C.35。...包含虚函数函数要么是公开函数,要么是保护非虚函数。...提示针对包含虚函数却没有虚函数销毁操作。

74120

《逆袭进大厂》第二弹之C++进阶篇59问59答(超硬核干货)

假设中采用是非虚函数,当删除指针指向派生对象时就不会触发动态绑定,因而只会调用函数,而不会调用派生函数。...,销毁一个对象时,先调用子类函数,然后再调用函数。...假设中采用是非虚函数,当删除指针指向派生对象时就不会触发动态绑定,因而只会调用函数,而不会调用派生函数。...2) 纯虚函数一定得定义,因为每一个派生函数会被编译器加以扩张,以静态调用方式调用其每一个虚以及一层函数。...虚拟继承子类中,子类会增加某种形式指针,或者指向子对象,或者指向一个相关表格;表格中存放不是虚子对象地址,就是其偏移量,此类指针被称为bptr,如上图所示。

2.2K40

后台开发:核心技术与应用实践 -- C++

而对于有虚函数来说,每个对象都会保存一个指向函数指针,该指针64位机器占8Byte。...派生时,派生是不能继承函数,也需要通过派生函数去调用函数。...派生中可以根据需要定义自己函数,用来对派生中所增加成员进行清理工作;清理工作仍然由函数负责。...执行派生函数时,系统会自动调用函数和子对象函数,对和子对象进行清理。...C++明确指出,当derived class 对象经由 base class 指针删除 而该 base class 带着一个non-virtual 函数, 导致对象 derived 成分没被销毁掉

1.3K10

轻松搞定面试中“虚”

是否每个函数都要设置成virtual?是否可以将函数设置成内联函数。 这样做是为了当用一个指针删除一个派生对象时,派生函数会被调用。...时候会首先调用子类函数掉对象中子类部分,然后调用函数部分,如果在函数里面调用虚函数,会导致其调用已经子类对象里面的函数,这是非常危险。...虚拟继承与普通继承不同是,虚拟继承可以防止出现diamond继承时,一个派生中同时出现了两个子对象。也就是说,为了保证这一点,虚拟继承情况下,子对象布局是不同于普通继承。...因此,它需要多出一个指向子对象指针。 8.什么是虚函数表?...为实现动态联编,编译器为每个包含虚函数创建一个表,称为vtable,vtable中,编译器放置了特定函数地址,每个带有虚函数中编译器会秘密地设置一个虚函数指针,称为vptr,指向对象

65120

计算机考研复试C语言常见面试题「建议收藏」

使用智能指针可以很大程度上避免这个问题,因为智能指针就是一个,当超出了作用域时,会自动调用函数函数会自动释放资源。...中实现纯虚函数方法是函数原型后加“=0” 如:virtual void funtion1()=0 如果A中virtual去掉以后,以上结果将会是Afoo 16、为什么函数必须是虚函数...为什么C++默认函数不是虚函数 函数设置为虚函数可以保证我们new一个子类时,可以使用指针指向该子类对象,释放指针时可以释放掉子类空间,防止内存泄漏。...C++默认函数不是虚函数是因为虚函数需要额外函数表和虚表指针,占用额外内存。而对于不会被继承来说,其函数如果是虚函数,就会浪费内存。...19、构造和顺序 构造: 成员对象构造函数 构造函数 子类成员对象构造函数 子类构造函数 : 子类函数 子类成员函数 函数 成员函数 两者正好相反

1.5K30

C++ this指针:用于成员函数指向调用该函数对象

C++中this指针是一个指向当前对象指针成员函数中,可以使用this指针来访问调用该函数对象成员变量和成员函数。...一、定义和使用this指针 this指针成员函数内部定义一个常量指针。它存储了当前对象地址,可以通过它访问当前对象成员变量和成员函数。...二、作为返回值this指针 this指针可以作为返回值返回。这种情况下,返回指向调用该函数对象指针。为了实现这个功能,需要将返回类型设置为引用或指针类型。...函数内部,返回指向调用该函数对象指针。...四、总结 this指针C++中是一个非常重要概念,可以用来访问调用该函数对象,作为返回值返回,或者作为函数参数传递。掌握this指针使用可以帮助我们更好地编写面向对象程序。

18240

CC++面试常问题集(2)

因此,创建子类对象时,为了初始化从父继承来数据成员,系统需要调用其父构造方法。 二,函数  函数也不会被子类继承,只是子类函数中会调用父函数。...三,赋值运算符重载函数  赋值运算符重载函数也不会被子类继承,只是子类赋值运算符重载函数中会调用父赋值运算符重载函数。 7、函数为什么要用virtual虚函数?...C++采用virtual虚函数是为了防止内存泄漏 具体地说,如果派生中申请了内存空间,并在其函数中对这些内存空间进行释放。...假设中采用是非虚函数,当删除指针指向派生对象时就不会触发动态绑定,因而只会调用函数,而不会调用派生函数。...那么在这种情况下,派生中申请空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况发生,C++函数应采用virtual虚函数

1.1K10

浅谈C++那些内存泄露

派生DS总先调用person构造函数,然后派生DS调用自己构造函数,接着是自己函数,最后是person构造函数,执行结果例如以下图所看到: 事实嘛,这个什么时候调构造...什么时候调派生构造()。我个人理解能够用简单图来表示了。构造和就像一个大框架包括着派生构造和: 1. 对于上述程序我main函数中继续改动,假设new了。...=new DS(); delete p; return 0; } 可是这次又出现故障了,执行结果中没有派生函数,这都是兼容惹祸,由于指针仅仅能指向派生继承自己那一部分...指针指针,管他三七二十一。我这个时候仅仅要在person函数中加一个virtual(虚特性)。尽管main函数中,还是第三中情况。...new了一块int型整型单元,并给*p赋值3,之后呢,输出*p和p地址。之后我delete p。事实我们每次delete实际删除是p指向那块空间值。

47710

从零开始学C++之虚函数与多态(一):虚函数指针、虚函数、object slicing与虚函数C++对象模型图

指针指向派生对象,调用是派生对象函数(间接)     p->Fun2();     p->Fun3();      // Fun3非虚函数,根据p指针实际类型来调用相应成员函数(直接...调用B构造函数时,先会调用BA构造函数。然后A构造函数里调用Print。由于此时实例类型B部分还没有构造好,本质它只是A一个实例,它函数指针指向是类型A函数表。...当你可能通过指针删除派生对象时 如果你打算允许其他人通过指针调用对象函数(通过delete这样做是正常),并且被派生对象是有重要函数需要执行,就需要让函数作为虚函数...即通过delete 指针删除了派生对象(执行派生函数),此时就好像delete 派生指针 效果一样。如果函数没有声明为virtual, 此时只会输出~Base。...六、C++对象模型图 Rectangle 继承自Shape,Shape函数为虚函数,draw为纯虚函数 ? ?

94600

C++】从零开始认识继承

那么我们很自然想到派生函数中调用: 但是报错了??? 因为子类也会隐藏父!!!...其实,派生函数会在被调用完成后自动调用函数清理成员。因为这样才能保证派生对象先清理派生成员再清理成员顺序。...所以我们不必派生函数中进行调用函数,不然就会重复释放同一块空间,导致报错! 因为必须要按先子后父顺序,父亲没了何谈子呢?...派生函数会在被调用完成后自动调用函数清理成员。因为这样才能保证派生对象先清理派生成员再清理成员顺序。 派生对象初始化先调用构造再调派生构造。...派生对象清理先调用派生再调。 因为后续一些场景函数需要构成重写,重写条件之一是函数名相同(这个我们后面会讲解)。

5110

浅析C++内存布局

函数B.3.中详述。怎么才算是覆写?——继承里,子类里含有与父里同名函数函数名、函数返回值类型和参数列表必须相同,权限可以不同。...如上面示例中,B和C都覆写了AfuncA_v1()。下面的例子说明了这一点: 2.3. 虚函数 《Effective C++》第三版,Item 07:为多态声明virtual函数。...当一个派生对象经由一个base class指针删除,而该base class带着一个non-virtual函数,其结果未有定义——实际执行时通常发生是对象derived成分没被销毁。...所以上述设计其实有错误,带多态性质应该声明一个virtual函数。如果class带有任何virtual函数,它就应该拥有一个virtual函数。...接下来示例中,我们将加上虚函数。 多重继承 3.1.

44810

Cpp虚函数相关知识点

当子类child继承base时候,创建一个base指针,让它 指向子类对象,这时候用指针调用print(),此时会自动判断,然后调用子类中函数, 如果不加virtual,指针就直接调用...可以看这一篇文章探索C++函数g++中实现,讲很详细。 函数为什么是虚函数 明白了虚函数特点,这个问题就不难了。...当指针指向子类对象时候,在对象使用完毕需要释放时,肯定需要调用子类对象函数呀,所以这种情况下函数也得是虚函数。...也可以看这段话: 指针可以指向派生对象(多态性),如果删除指针delete []p; 就会调用该指针指向派生函数,而派生函数又自动调用 函数,这样整个派生对象完全被释放...如果函数不被声明成虚函数,则编译器实施静态绑定, 删除指针时,只会调用函数而不调用派生函数, 这样就会造成派生对象不完全。所以,将函数 声明为虚函数是十分必要

35620
领券