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

【C++】匿名对象 ③ ( 函数返回值为对象 匿名对象 的 拷贝构造函数函数 调用情况分析 )

, 以及不同的使用场景下 , 匿名对象 的 创建与销毁情况 ; C++ 编译器 发现 使用 匿名对象 , 根据 匿名对象 的用法 , 决定对 匿名对象的 处理 ; 匿名对象单独使用 : 如果只是单纯的使用...fun 函数中 , 函数返回对象 , 创建 要返回的 普通对象副本 , 也就是一个 匿名对象 ; 调用函数 : m_age = 12 这是 fun 函数执行完毕 , 在函数作用域中的 普通对象...执行结果如下 : 调用带参数构造函数 m_age = 18 调用带参数构造函数 m_age = 12 调用拷贝构造函数 调用函数 : m_age = 12 调用函数 : m_age = 12...匿名对象 ; 调用函数 : m_age = 12 这是 fun 函数执行完毕 , 在函数作用域中的 普通对象 需要被销毁 ; 调用函数 : m_age = 12 这是在 main 函数中..."); return 0; } 执行结果 : 调用带参数构造函数 m_age = 18 调用带参数构造函数 m_age = 12 调用拷贝构造函数 调用函数 : m_age = 12 调用函数

26020

轻松搞定面试中的“虚”

在类外定义虚函数,不必再加virtual。该函数就是虚函数了。虚函数是多态性的基础,其调用的方式是动态联编(程序运行时才决定调用基类的还是子类)。...是否每个类的函数都要设置成virtual?是否可以将函数设置成内联函数。 这样做是为了当用一个基类的指针删除一个派生类的对象派生类的函数会被调用。...5.是否可以将构造函数声明为virtual? 虚函数的意思就是开启动态绑定,程序根据对象的动态类型来选择要调用的方法。...(动态绑定是根据对象的动态类型而不是函数名,在调用构造函数之前,这个对象根本就不存在,它怎么动态绑定?) 6.是否可以在函数或者构造函数调用函数? 在构造函数不要调用函数。...在的时候会首先调用子类的函数对象中的子类部分,然后在调用基类的函数基类部分,如果在基类的函数里面调用函数导致其调用已经了的子类对象里面的函数,这是非常危险的。

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

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

函数应该是虚函数吗?也就是说,是否应该允许通过指向基类的指针进行销毁?如果是,则base的函数必须是公共的才能被调用,否则虚拟调用它会导致未定义的行为。...否则,应该对其进行保护,以便只有派生类才能在自己的函数调用它,这个函数也应该是非虚的,因为它不需要虚拟地运行。...对于基类Base,调用代码可能尝试通过指向Base的指针销毁派生对象,例如在使用unique_ptr 。...如果Base的函数是公共的和非虚拟的(默认值),则可能会意外地在实际上指向派生对象的指针上调用它,在这种情况下,尝试删除的行为是不确定的。...推论:编写基类,请始终显式编写一个函数,因为隐式生成的是公共的和非虚的。如果默认函数就很好,那么您只需要决定器可见性和虚函数性,则实现可以直接使用=default。

1.1K20

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

2、在遇到通过基类指针或引用调用函数的语句,首先根据指针或引用的静态类型来判断所调函数是否属于该class或者它的某个public 基类,如果 属于再进行调用语句的改写: (*(p->_vptr[slotNum....从而就导致了基类的函数调用了,而派生类的函数没有调用这个问题发生....如果没有这样做的话,只会输出基类的 函数,这种输出情况通过比对规则2也可以理解,pI 现在虽然指向派生对象首地址,但执行pI->~IRectangle() 发现不是虚函数,故直接调用, 假如在派生函数内有释放内存资源的操作...更甚者,问题远远没那么简单,我们知道delete pI ; 调用函数,再释 放内存(operator delete),上面的例子因为派生类和基类现在的大小都是4个字节即一个vptr,故不存在释放内存崩溃的情况.../test )检测,并没有内存泄漏,基类和派生类的函数也正常被调用

97520

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

,先调用基类的构造函数,再调用派生类的构造函数派生对象销毁,先调用派生类的函数,再调用基类的函数。...函数是否可以为虚函数?如果可以,有什么作用? 函数可以是虚函数,因为它是对象结束调用,不影响虚表构建。...,此时我们把类A的函数修改为virtual,看看结果: A() B() ~B() ~A() 一般情况下,只有当一个类被用作基类才需要使用虚函数,这样做的作用是当一个基类的指针删除派生类的对象...因为销毁的时候直接销毁的基类指针,此时编译器只知道调用基类,并不会主动去调用派生类的函数,所以基类函数需为虚函数,这样运行时程序才会去调用派生类的函数,其实这就相当于函数的多态,...基于多态的作用,这个指向派生类的基类指针调用派生类的函数,然后再调用基类的函数

91410

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

2、在遇到通过基类指针或引用调用函数的语句,首先根据指针或引用的静态类型来判断所调函数是否属于该class或者它的某个public 基类,如果 属于再进行调用语句的改写: (*(p->_vptr[slotNum....从而就导致了基类的函数调用了,而派生类的函数没有调用这个问题发生....如果没有这样做的话,只会输出基类的 函数,这种输出情况通过比对规则2也可以理解,pI 现在虽然指向派生对象首地址,但执行pI->~IRectangle() 发现不是虚函数,故直接调用, 假如在派生函数内有释放内存资源的操作...更甚者,问题远远没那么简单,我们知道delete pI ; 调用函数,再释 放内存(operator delete),上面的例子因为派生类和基类现在的大小都是4个字节即一个vptr,故不存在释放内存崩溃的情况.../test )检测,并没有内存泄漏,基类和派生类的函数也正常被调用

92500

《Effective C++》读书笔记(二):构造赋值运算(条款05~条款12)

而对于类中的自定义类型,它们自动调用的构造和函数,如果是别的类的自定义类型,则会到它们自己的类中去调用它们的构造和函数。在多态中,基类先构造,然后再是派生类构造。...在看到这个条款,我立马就会想到它的意思了:那就是在多态中,给基类的函数声明为virtual虚函数,这样就会保证资源不会被泄漏,因为当基类的指针或者引用指向了派生类的对象,在的时候,先会派生类的成分...,因此解决办法就是将这个抛异常的函数拿出来,不要放到函数中,然后使用“双保险”的方式,再在函数中判断是否已经将这个函数执行完毕(如果抛异常就是没执行完毕),如果没有执行完毕,再在函数中执行...,在构造函数调用的时候,先去构造基类的成分,然后才会去构造派生类的从成分,这就意味着,先去调用基类的构造函数。...同样的,对于函数也一样,由于是先派生类的成分,在派生函数执行的时候,对象内的派生类的成员变量就是变成了未定义值,C++是它们不存在,而进入了基类的函数,就会变成基类的对象

34310

构造函数为什么一般不定义为虚函数?而函数一般写成虚函数的原因 ?

而在构造一个对象,由于对象还未创建成功,编译器无法知道对象的实际类型,是类本身还是类的派生类等等 2)虚函数调用需要虚函数表指针,而该指针存放在对象的内存空间中;若构造函数声明为虚函数,那么由于对象还未创建...,还没有内存空间,更没有虚函数表地址用来调用函数即构造函数了 2、函数最好声明为虚函数,首先函数可以为虚函数,当一个指向派生类的基类指针,最好将基类的函数声明为虚函数,否则可以存在内存泄露的问题...如果函数不被声明成虚函数,则编译器实施静态绑定,在删除指向派生类的基类指针,只会调用基类的函数而不调用派生函数,这样就会造成派生对象不完全。子类,要调用父类的函数吗?...函数调用的次序时先派生类后基类的。和构造函数的执行顺序相反。并且函数要是virtual的,否则如果用父类的指针指向子类对象的时候,函数静态绑定,不会调用子类的。...不用显式调用自动调用

60010

《挑战30天C++入门极限》C++中类的多态与虚函数的使用

C++中类的多态与虚函数的使用   类的多态特性是支持面向对象的语言最主要的特性,有过非面向对象语言开发经历的人,通常对这一章节的内容觉得不习惯,因为很多人错误的认为,支持类的封装的语言就是支持面向对象的...但是在实际工作中,很可能碰到对象所属类不清的情况,下面我们来看一下派生类成员作为函数参数传递的例子,代码如下: //例程2 #include using namespace...cout<<speed<<"|"<<total<<"|"<<aird<<endl; } virtual ~Car() { cout<<"载入Car派生函数...DelPN(a);后,在的时候,系统成功的确定了先调用Car类的函数,而如果将函数的virtual修饰去掉,再观察结果,会发现的时候,始终调用了基类的函数,由此我们发现,多态的特性的...virtual修饰,不单单对基类和派生类的普通成员函数有必要,而且对于基类和派生类的函数同样重要。

68910

C++虚函数解析

派生对象从内存中撤销一般先运行派生类的函数,然后再调用基类的函数。...如果用new运算符建立的派生类的临时对象,对指向基类的指针指向这个临时对象当用delete运算符撤销对象,系统执行的是基类的函数,而不是派生类的函数,不能彻底的“清理现场”。...解决的方法是将基类及派生类的函数设为虚函数,这时无论基类指针指向哪个派生对象,系统采用动态关联,调用相应的函数对象进行清理。...这样就达到我们的目的了,基类,派生类都调用函数,另外需要注意的是 在基类的函数声明为虚函数,由该基类派生函数也自动成为虚函数,即使派生类的函数与基类的函数名字不相同。  ...程序中显示的用delete运算符删除一个对象,而这个对象是指向派生对象的基类指针,系统调用相应派生类的函数

91370

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

由于vptr在对象中的偏移不会随着派生层次的增加而改变,而且改写的虚函数派生类vtable中的位置与它在基类vtable中的位置始终保持一致,有了这两条保证,再加上被改写虚函数与其基类中对应虚函数的原型和调用规范都保持一致...所以结果是分别调用的是Base::doPrint和Derived::doPrint2。 四、虚函数 何时需要虚函数?...当你可能通过基类指针删除派生对象 如果你打算允许其他人通过基类指针调用对象函数(通过delete这样做是正常的),并且被派生对象是有重要的函数需要执行,就需要让基类的函数作为虚函数...即通过delete 基类指针删除派生对象(执行派生函数),此时就好像delete 派生类指针 效果一样。如果基类函数没有声明为virtual, 此时只会输出~Base。...此外还可以看到,调用了两次CDocument构造函数和一次CDocument 拷贝构造函数,CDocument函数调用3次。

1K00

C++:51---继承中的构造函数函数、拷贝控制一系列规则

派生类释放,先执行派生类的函数,再执行基类的函数 二、继承中被删除函数的语法 基类或派生类可以将其构造函数或者拷贝控制成员定义为删除的。...规则如下: 如果基类中的默认构造函数、拷贝构造函数、拷贝赋值运算符、或函数是被删除的或者是不可访问的,则派生类中对应的成员将是删除的,原因是编译器不能使用基类成员来执行派生对象中属于基类的部分操作...如果在基类中有一个不可访问或删除掉的函数,则派生类中合成的默认和拷贝构造函数将是被删除的,因为编译器无法销毁派生对象的基类部分 编译器不会合成一个删除掉的移动操作。...根据构造函数函数我们知道: 派生类构造,先构造基类部分,然后再构造派生类部分 派生,先派生类部分,然后再基类部分 因此: 在基类构造函数执行的时候,派生类的部分是未定义状态 在基类函数执行的时候...,派生类的部分已经被释放了 所以在基类的构造函数函数调用函数是不建议的,因为: 虚函数在执行的时候可能会调用到属于派生类的成员,而此时派生类可能还未构造/或者已经被释放了,因此程序可能崩溃

1.3K30

《C++Primer》第十五章 面向对象程序设计

当我们delete一个动态分配的对象的指针将执行函数,如果该指针指向继承体系中的某个类型,那么可能出现指针的静态类型与被删除对象的动态类型不符合的情况。...另外某些定义基类的方式也可能导致有的派生类成员称为被删除函数: 如果基类中的默认构造函数、拷贝构造函数、拷贝赋值运算或函数是被删除函数或者不可访问,则派生类中对应的成员将是被删除的,原因是编译器不能使用基类成员来执行派生对象基类部分的构造...、赋值或者销毁操作 如果在基类中有一个不可访问或者删掉的函数,则派生类中合成的默认和拷贝构造函数将是被删除的,原因是编译器无法销毁掉派生类的基类部分 当我们使用=default请求一个移动操作,如果基类中的对应操作是删除或者不可访问的...在构造函数函数调用函数 派生对象的基类部分首先被构造,然后再构造派生类部分。对象销毁的顺序正好相反,派生函数首先执行,然后是基类的函数。...当执行基类的构造函数,该对象派生类部分是未被初始化的状态;当执行基类的函数派生类部分已经被销毁了。

1.2K20

C++学习笔记 -- 虚函数与纯虚函数

开始学C++了,所以又重拾以前学习过的相关概念… 函数是当一个对象的生命周期结束自动执行函数。...虚函数表的作用是用来实现多态,但同时也带来了执行效率和额外内存空间的增加。 再来看虚函数,它所存在的意义:基类的指针指向派生对象,用基类的指针删除派生对象。...假定:基类的函数调用派生类要早,造成的一种情况就是类成员不存在了,而类本身却还在,但是类存在的情况下,类成员应该还存在。...所以这就矛盾了,所以派生类的函数先被调用,基类的函数再被调用。...… B::f() A::ff() //定义指向基类对象的指针a,当调用f()方法,因为f为虚函数,所以调用派生类的f(),输出B::f(); 参考: 详解C++中的纯虚函数(虚函数区别)&多态性以及实例应用

1.5K40

1小精通c++面向对象编程

图5-6 动态联编示例 5.4 虚函数函数是动态束定的基础函数是非static成员函数 格式:virtual () 若类中一成员函数被说明为虚函数,则该成员函数派生类中可能有不同的实现...当使用该成员函数操作指针或引用所标识的对象,对该成员函数调用可采用动态束定方式 动态束定只能通过指针或引用标识对象来操作虚函数。...在成员函数内可以调用纯虚函数,但在构造函数函数内不能调用纯虚函数(纯虚函数没有实现代码) 5.6.1 抽象类的作用 1用作基类:在一个继承层次结构中,提供一个公共的根,并基于抽象类的操作设计出对抽象类所描述的一类对象进行操作的公共接口...图5-14 抽象类 5.7 虚函数函数前加关键字virtual进行说明,则该函数称为虚函数 如果一个类的函数被说明为虚函数,则它的派生类中的函数也是虚函数,不管它是否使用了关键字...virtual进行说明 子类型化要求函数被声明为虚函数,尤其是在函数要完成一些有意义的工作,构造函数不能被声明为虚函数 目的:使用delete运算符删除一个对象,能保证函数被正确地执行

82030

掌握了多态的特性,写英雄联盟的代码更少啦!

在构造函数函数调用「虚函数」,不是多态。 编译即可确定,调用函数是自己的类或基类中定义的函数,不会等到运行时才决定调用自己的还是派生类的函数。 我们看如下的代码例子,来说明: ?...---- — 5 — 虚函数 函数是在删除对象或退出程序的时候,自动调用函数,其目的是做一些资源释放。...那么在多态的情景下,通过基类的指针删除派生对象,通常情况下只调用基类的函数,这就会存在派生对象函数没有调用到,存在资源泄露的情况。...pa指针对象,B 类的函数没有被调用。...解决办法:把基类的函数声明为virtual 派生类的函数可以 virtual 不进行声明; 通过基类的指针删除派生对象,首先调用派生类的函数,然后调用基类的函数,还是遵循「先构造,后虚构

50610

Cpp虚函数相关知识点

当子类child继承base的时候,创建一个base类的指针,让它 指向子类对象,这时候用基类指针调用print(),此时会自动判断,然后调用子类中的函数, 如果基类不加virtual,基类指针就直接调用基类的...当基类指针指向子类对象的时候,在对象使用完毕需要释放,肯定需要调用子类对象函数呀,所以这种情况下函数也得是虚函数。...也可以看这段话: 基类指针可以指向派生类的对象(多态性),如果删除该指针delete []p; 就会调用该指针指向的派生函数,而派生类的函数又自动调用 基类的函数,这样整个派生类的对象完全被释放...如果函数不被声明成虚函数,则编译器实施静态绑定, 在删除基类指针,只会调用基类的函数而不调用派生函数, 这样就会造成派生对象不完全。所以,将函数 声明为虚函数是十分必要的。...纯虚函数让类成为抽象类,即不能被实例化。 声明为虚函数只是要求子类必须给出实现,但基类中也可以写出纯虚函数的实现。 函数可以是纯虚函数

36720

第 15 章 面向对象程序设计

函数的虚属性会被继承,无论派生类中使用合成的函数还是自定义的函数,都将是虚函数。这样,就能保证 delete基类指针总能运行正确的函数版本。...假如基类函数不是虚函数,且指针的静态类型与动态类型不一致,则此时只能调用基类的函数,那派生对象的部分则无法完成,从而产生未定义行为。...如果在基类中有一个不可访问和删除掉的函数,则派生类中合成的默认拷贝构造函数将是删除的,因为编译器无法销毁派生对象的基类部分。 和过去一样,编译器将不会隐式合成一个删除掉的移动操作。...同样,如果基类的函数删除的或不可访问的,则派生类的移动构造函数也将是被删除的。...在派生类中定义除函数之外的其他拷贝控制成员,都需要显式的进行基类的相应操作。而函数则只用负责销毁派生类自己分配的资源,派生对象的基类部分时自动销毁的。

1K30

C++面向对象编程一些拾遗

所以,当我们决定一个类是否需要定义它自己版本的拷贝控制成员,一个原则是首先考虑其是否需要一个函数,通常,对函数的需求比对拷贝构造函数和赋值运算符的需求更为明显,如果需要一个函数,我们几乎可以肯定它也需要一个拷贝构造函数和一个赋值运算符...派生类构造前,调用基类的构造函数来构造继承来的成员,当一个派生类有多个基类,那么按照类定义的时候的继承顺序来依次调用基类的构造函数。...派生类的函数。 和对象构造的时候刚好是相反的顺序。 对派生类的新增普通成员进行清理。 调用成员对象函数调用基类函数。 十.继承和虚函数。 1. 覆盖基类的函数。...多态的意思就是多种形态,当调用成员函数,编译器根据不同的对象类型来选择不同的成员函数调用。...定义成虚函数的好处是,当我们准备这个指针所指向的对象,可以根据指针所指对象的类型(基类还是派生类)来执行不同的函数,防止内存泄漏。详细参见:对于虚函数的理解。 6.

65620

函数(C#)

函数又称终结器,用于类的实例。 定义   函数(destructor) 与构造函数相反,当对象结束其生命周期(例如对象所在的函数调用完毕),系统自动执行函数。...函数往往用来做“清理善后” 的工作(例如在建立对象用new开辟了一片内存空间,delete自动调用函数后释放内存)。...如果用户没有编写函数,编译系统自动生成一个缺省的函数(即使自定义了函数,编译器也总是会为我们合成一个函数,并且如果自定义了函数,编译器在执行时会先调用自定义的函数调用合成的函数...程序员无法控制何时调用函数,因为这是由垃圾回收器决定的。垃圾回收器检查是否存在应用程序不再使用的对象。如果垃圾回收器认为某个对象符合,则调用函数(如果有)并回收用来存储此对象的内存。...程序退出也会调用函数。 可以通过调用 Collect 强制进行垃圾回收,但大多数情况下应避免这样做,因为这样导致性能问题有关更多信息,请参见强制垃圾回收。

1.7K70
领券