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

虚函数是如何工作的,当新的返回类型被赋值时会发生什么?

虚函数是一种在面向对象编程中使用的特殊函数。它允许子类重写父类的函数,并且在运行时根据对象的实际类型来调用相应的函数实现。

虚函数的工作原理是通过虚函数表(vtable)来实现的。每个包含虚函数的类都会有一个虚函数表,该表是一个指针数组,其中存储了该类的虚函数的地址。当一个对象被创建时,会在对象的内存布局中添加一个指向虚函数表的指针。

当调用一个虚函数时,编译器会根据对象的实际类型找到对应的虚函数表,并通过表中的函数指针来调用正确的函数实现。这个过程称为动态绑定或后期绑定。

当新的返回类型被赋值时,会根据对象的实际类型来确定调用的函数实现。如果子类重写了父类的虚函数,并且返回类型不同,那么在调用该虚函数时会根据子类的返回类型来执行相应的函数实现。

举例来说,假设有一个基类Animal和一个派生类Dog,它们都有一个虚函数makeSound()。在基类Animal中,makeSound()的返回类型是void,而在派生类Dog中,makeSound()的返回类型是string。当我们创建一个Dog对象并调用makeSound()时,会根据对象的实际类型来确定调用的函数实现。如果我们将makeSound()的返回值赋给一个变量,那么变量的类型将根据对象的实际类型而确定。

虚函数的优势在于它提供了一种灵活的方式来实现多态性,使得程序可以根据对象的实际类型来调用正确的函数实现。这样可以简化代码的设计和维护,并且提高代码的可扩展性和可重用性。

在腾讯云的产品中,与虚函数相关的概念可能不直接存在,但可以通过使用云服务器(CVM)来支持开发和部署面向对象编程的应用程序。云服务器提供了可扩展的计算资源,可以满足各种应用程序的需求。您可以通过以下链接了解更多关于腾讯云服务器的信息:

请注意,以上答案仅供参考,具体的产品选择和使用应根据实际需求和情况进行评估和决策。

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

相关·内容

Effective_Cpp中的55个建议

9:绝对不要在构造和析构过程中调用虚函数 当构造子类的时候,需要先去调用父类的构造函数,这时候子类还不存在,是无法去自动调用子类的虚函数的。...设计class犹如设计type 1.定义出高效的classes是一种挑战,可以从这些方面考虑: 新type的对象应该如何创建和销毁? 对象的初始化和对象的赋值该有什么样的差别?...新type的对象如果被passed by value,意味着什么? 什么是新type的合法值? 你的新type需要配合某个继承图系吗? 你的新type需要什么样的转换?...什么样的操作符和函数对此新type而言是合理的? 什么样的标准函数应该驳回? 谁该取用新type的成员? 什么是新type的未声明接口? 你的新type有多么一般化?...3.切割问题:当使用传值方式时,一个子类对象被传递,被当一个父类对象接收时,此时只能调用父类中拥有的操作,子类扩展的就被切割了。 21:?必须返回对象时,别妄想返回其reference。

60830

C++基础闯关100题,你能闯多少?【2021超硬核大厂高频面试题】

,malloc返回void*指针,需要强制类型转换 new可以被重载,malloc不能 10、new和delete是如何实现的?...new的实现过程是:首先调用名为operator new的标准库函数,分配足够大的原始为类型化的内存,以保存指定类型的一个对象;接下来运行该类型的一个构造函数,用指定初始化构造对象;最后返回指向新分配并构造后的的对象的指针...结果是编译器并不会报错,因为它并不知道你的目的是重写虚函数,而是把它当成了新的函数。 如果这个虚函数很重要的话,那就会对整个程序不利。...当拷贝构造函数为private时:语句3和语句4在编译时会报错。 使用explicit修饰构造函数时:如果构造函数存在隐式转换,编译时会报错。 31、初始化和赋值的区别?...,重写就是重写函数体,要求基类函数必须是虚函数且: 与基类的虚函数有相同的参数个数 与基类的虚函数有相同的参数类型 与基类的虚函数有相同的返回值类型 //父类 class A{

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

    malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。 62、delete p、delete [] p、allocator都有什么作用?...由于对象成员变量的初始化动作发生在进入构造函数之前,对于内置类型没什么影响,但如果有些成员是类,那么在进入构造函数之前,会先调用一次默认构造函数,进入构造函数后所做的事其实是一次赋值操作(对象已存在),...,再将func()函数的返回地址、func()函数的参数从右到左、func()定义变量依次压栈; 当func()调用f()的时候,编译器此时会将func()函数的运行状态进行压栈,再将的返回地址、f()...当退出函数的时候,临时变量可能被销毁,但是返回值却被放到寄存器中与临时变量的生命周期没有关系 如果我们需要返回值,一般使用赋值语句就可以了 《【C++】临时变量不能作为函数的返回值?》...拷贝构造函数是函数,赋值运算符是运算符重载。 拷贝构造函数会生成新的类对象,赋值运算符不能。

    2.4K40

    当类构造与析构的时候...

    关于虚函数部分不在这篇再提,上一篇提过了。 文章目录 什么时候会调用默认构造函数 什么时候调用拷贝构造函数? 什么时候调用赋值运算符? 深拷贝与浅拷贝 成员初始化列表的概念,为什么用它会快一些?...1、用类的一个实例化对象去初始化另一个对象的时候 2、函数的参数是类的对象时(非引用传递) 3、函数的返回值是函数体内局部对象的类的对象时 ,此时虽然发生(Named return Value优化)...NRV优化,但是由于返回方式是值传递,所以会在返回值的地方调用拷贝构造函数 ---- 什么时候调用赋值运算符?...赋值运算符是执行某种运算,将一个对象的值复制给另一个对象(已经存在的)。调用的是拷贝构造函数还是赋值运算符,主要是看是否有新的对象实例产生。...析构的时候,如果有基类,且基类的析构函数是虚函数,则先调用自己的构造函数,再调用基类的构造函数。 如果基类的析构函数不是虚函数,则调用基类的析构函数。 ---- 继承机制中对象之间如何转换?

    64520

    你们要的C++面试题答案来了--基础篇

    请你回答一下为什么析构函数必须是虚函数?...请你来说一说隐式类型转换 参考回答: 首先,对于内置类型,低精度的变量给高精度变量赋值会发生隐式类型转换,其次,对于只存在单个参数的构造函数的对象构造来说,函数调用可以直接使用该参数传入,编译器会自动调用其构造函数生成临时对象...参考文章《变长参数探究》 请你说说C++如何处理返回值? 参考回答: 生成一个临时变量,把它的引用作为函数参数传入函数内。 请你回答一下C++中拷贝赋值函数的形参能否进行值传递? 参考回答: 不能。...左值可以被赋值,右值不可以被赋值,可以用来给左值赋值。 左值可变,右值不可变(仅对基础类型适用,用户自定义类型右值引用可以通过成员函数改变)。 4....请你来说一下reactor模型组成 参考回答: reactor模型要求主线程只负责监听文件描述上是否有事件发生,有的话就立即将该事件通知工作线程,除此之外,主线程不做任何其他实质性的工作,读写数据、接受新的连接以及处理客户请求均在工作线程中完成

    2.9K31

    C++知识总结

    (2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数...11.什么时候需要“引用” 流操作符>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。 12. 结构与联合有什么区别? 1....对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。 13.虚函数的使用方法是: 在基类用virtual声明成员函数为虚函数。...这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便地被调用。在类外定义虚函数时,不必再加virtual。...C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数都自动成为虚函数。

    1K40

    基础知识_Cpp

    什么是虚函数,实现原理是什么? 2.3. 面向对象三大特性 2.4. 编译时多态是怎样的 2.5. 类成员的权限控制 2.6. struct和class的区别 2.7....当类中声明虚函数之后,编译器会在类的开始位置设置一个指针,来指向一个虚函数列表,当子类继承父类时,会一块继承这个指针,如果子类对父类中的虚函数进行了重写,就会用新函数的地址覆盖虚函数表中的旧函数。...在一个有指针对象的类中至少要实现哪三个函数 拷贝构造函数、拷贝赋值运算符、析构函数 如果没有实现拷贝赋值运算符可能会遇到什么问题(深拷贝、浅拷贝) 浅拷贝,只拷贝指针的值,深拷贝会再开辟一块新空间,连同指针在堆中指向的内容一块拷贝过去...再就是函数的返回值也要用到指针指向的类型时,仅利用模板的参数推导是做不到的。 如何实现?...基类必须要有虚函数,因为 dynamic_cast 是运行时类型检查,需要运行时类型信息,而这个信息是存储在类的虚函数表中。

    2K30

    C++设计类的注意事项

    赋值操作符 要分清楚什么是赋值,什么是初始化,这是不同的: Star sirius; Star alpha = sirius;// 初始化 Star dogstar; dogstar = sirius;...同理,如果要做到不同类之间的赋值(也包括基类赋值给派生类),要么做强制类型转换再赋值,要么定义一个特定参数的赋值操作函数。 赋值操作符也是不能被继承的,毕竟其特征标(参数列表)随类而异。...当把对象作为返回值时,如果是传递的原始对象引用,那么要返回对象的引用,保证是传递的同一个对象,比如重载返回引用,按引用返回也可以节省时间。...但是如果返回的是函数中临时创建的新对象,那就只能按值返回,毕竟函数结束后这个新对象就会被析构了,必须复制一个对象来传递回去。...虚函数的意义是当用基类的指针或引用指向对象时(不管指向的是基类对象还是派生类对象),调用虚函数会根据对象真实类型调用对应方法。

    39920

    C++ 面试必备:常见 C++ 面试题汇总及详细解析

    C++和C的区别是什么? C++是C的超集,也就是说,C++包括了C的所有基础特性,并且还增加了一些新的特性。...引用也是C++中的一种数据类型,它提供了一种简洁而高效的方式来操作变量和对象,而不需要拷贝它们本身。引用被视为原变量的一个别名,其操作类似于指针,但是引用不能被赋值为NULL,也不能进行指针运算。...感兴趣的同学可以看我之前帖子,有详细介绍 如何避免野指针? 野指针是指指向已经被释放或者无效的内存空间的指针,这是 C++ 中常见的一个程序错误。...通过虚函数表和虚指针,使得程序能够在运行时根据对象的实际类型来确定调用哪个函数。 什么是虚函数? 虚函数是C++中的一种特殊函数,它可以实现多态性。...此时,程序会为函数创建一个新的栈帧,用于存储函数的局部变量、返回值等信息。栈帧包含了多个部分,例如函数参数、局部变量、返回地址等等。函数参数通过栈传递,在栈的顶部。局部变量则被分配在栈帧的底部。

    2.2K30

    《逆袭进大厂》之C++篇49问49答

    相比于C语言,C++提供了一些新的机制保障类型安全: 操作符new返回的指针类型严格与对象匹配,而不是void* C中很多以void*为参数的函数可以改写为C++模板函数,而模板是支持类型检查的; 引入...,派生类的虚表指针指向的是基类的虚表;当派生类对基类的虚函数重写时,派生类的虚表指针指向的是自身的虚表;当派生类中有自己的虚函数时,在自己的虚表中将此虚函数地址添加在后面 这样指向派生类的基类指针在运行时...深拷贝 深拷贝不仅拷贝值,还开辟出一块新的空间用来存放新的值,即使原先的对象被析构掉,释放内存了也不会影响到深拷贝得到的值。在自己实现拷贝赋值的时候,如果有指针变量的话是需要自己实现深拷贝的。...explicit 关键字作用于单个参数的构造函数 被explicit修饰的构造函数的类,不能发生相应的隐式类型转换 45、什么情况下会调用拷贝构造函数 用类的一个实例化对象去初始化另一个对象的时候 函数的参数是类的对象时...Linux g++ 下则不会发生拷贝构造函数,不仅如此即使返回局部对象的引用,依然不会发生拷贝构造函数 总结就是:即使发生NRV优化的情况下,Linux+ g++的环境是不管值返回方式还是引用方式返回的方式都不会发生拷贝构造函数

    2K10

    《逆袭进大厂》之C++篇49问49答(绝对的干货)

    相比于C语言,C++提供了一些新的机制保障类型安全: 操作符new返回的指针类型严格与对象匹配,而不是void* C中很多以void*为参数的函数可以改写为C++模板函数,而模板是支持类型检查的; 引入...,派生类的虚表指针指向的是基类的虚表;当派生类对基类的虚函数重写时,派生类的虚表指针指向的是自身的虚表;当派生类中有自己的虚函数时,在自己的虚表中将此虚函数地址添加在后面 这样指向派生类的基类指针在运行时...深拷贝 深拷贝不仅拷贝值,还开辟出一块新的空间用来存放新的值,即使原先的对象被析构掉,释放内存了也不会影响到深拷贝得到的值。在自己实现拷贝赋值的时候,如果有指针变量的话是需要自己实现深拷贝的。...explicit 关键字作用于单个参数的构造函数 被explicit修饰的构造函数的类,不能发生相应的隐式类型转换 45、什么情况下会调用拷贝构造函数 用类的一个实例化对象去初始化另一个对象的时候 函数的参数是类的对象时...Linux g++ 下则不会发生拷贝构造函数,不仅如此即使返回局部对象的引用,依然不会发生拷贝构造函数 总结就是:即使发生NRV优化的情况下,Linux+ g++的环境是不管值返回方式还是引用方式返回的方式都不会发生拷贝构造函数

    2.6K40

    C++面试题

    ,当计数为0时自动释放资源;构造新的weak_ptr指针不会增加shared_ptr的引用计数,是用来解决shared_ptr循环引用的问题。...但是,当这一系列构造函数调用正发生时,每个构造函数都已经设置VPTR指向它自己的VTABLE。...但是不论如何它依旧遵守多态的规则,也就是说,如果你的析构函数是虚函数,调用虚函数的规则也遵守多态原则,也就是会调用子类的析构函数,这和其他虚函数的机制完全一致,并没有什么不同。...C++引入这个机制是为了让程序在运行时能根据基类的指针或引用来获得该指针或引用所指的对象的实际类型。简单的讲,RTTI是在一个类的虚函数表里面添加了一个新的类型条目。...C++的空类有哪些成员函数 默认构造函数、 默认拷贝构造函数、 默认析构函数、 默认赋值运算符,以及取址运算符和 const 取址运算符。 10. 虚函数表属于类还是对象?虚函数表什么内存空间?

    1.7K42

    C++笔试面试题整理

    因此,使用reinterpret_casts的代码很难移植。reinterpret_casts的最普通的用途就是在函数指针类型之间进行转换。 什么是封装?C++中是如何实现的?...const修饰函数的返回值:如果给“指针传递”的函数返回值加const,则返回值不能被直接修改,且该返回值只能被赋值给const修饰的同类型指针。...使用时会对编译器有什么暗示。...这个操作符象流操作符一样,是可以连续使用的,例如:x = j = 10;或者(x=10)=100;赋值操作符的返回值必须是一个左值,以便可以被继续赋值。因此引用成了这个操作符的惟一返回值选择。...有哪几种情况只能用初始化列表,而不能用赋值? 当类中含有const、引用成员变量以及基类的构造函数都需要初始化列表。 虚函数是怎么实现的? 简单地说,虚函数是通过虚函数表实现的。

    2.6K40

    《逆袭进大厂》第三弹之C++提高篇79问79答

    通过覆写赋值运算符,才能将一个旧的智能指针赋值给另一个指针,同时旧的引用计数减1,新的引用计数加1 2) 一个构造函数、拷贝构造函数、复制构造函数、析构函数、移走函数; 117、说一说你理解的内存对齐以及原因...1) 拷贝构造函数的作用就是用来复制对象的,在使用这个对象的实例来初始化这个对象的一个新的实例。 2) 参数传递过程到底发生了什么?...对于这种情形可以很好的工作,但是下面几种情形是不可以这么使用的; 2) 类含有虚函数表:这么做会破坏虚函数表,后续对虚函数的调用都将出现异常; 3) 类中含有C++类型的对象:例如,类中定义了一个list...调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某种特定原型、某些限制条件(如返回值为int)的被调用函数。 178、什么是一致性哈希?...当一个成员函数被声明为虚函数之后,其派生类中同名函数自动成为虚函数,在派生类中重新定义此函数时要求函数名、返回值类型、参数个数和类型全部与基类函数相同。

    2.2K30

    硬核 | C++ 基础大全

    如果没有显示的写赋值运算符的重载,系统也会生成默认的赋值运算符,做一些基本的拷贝工作。...” 理解这些声明的技巧在于,查看关键字const右边来确定什么被声明为常量 ,如果该关键字的右边是类型,则值是常量;如果关键字的右边是指针变量,则指针本身是常量。...一个对象以值传递的方式从函数返回,需要执行拷贝构造函数创建一个临时对象作为返回值。 一个对象需要通过另外一个对象进行初始化。 为什么拷贝构造函数必需时引用传递,不能是值传递? 为了防止递归调用。...fork 从父进程返回子进程的 pid,从子进程返回 0,调用了 wait 的父进程将会发生阻塞,直到有子进程状态改变,执行成功返回 0,错误返回 -1。...哪些函数不能是虚函数 构造函数,构造函数初始化对象,派生类必须知道基类函数干了什么,才能进行构造;当有虚函数时,每一个类有一个虚表,每一个对象有一个虚表指针,虚表指针在构造函数中初始化; 内联函数,内联函数表示在编译阶段进行函数体的替换操作

    1.2K10

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

    , bulk, 20); // bulk是Bulk_Quote类型 在C++中,我们使用基类的引用或者指针调用一个虚函数时会发生动态绑定。...一般情况下派生类中虚函数返回类型是类本身的指针或引用时,上述规则无效。比如D由B派生而来,则基类的虚函数可以返回B*而派生类的对应函数可以返回D*。...即使静态类型和动态类型可能不一致(当使用基类的引用或者指针时可能发生这种情况),但是我们能使用哪些成员仍然是静态类型决定的。...虚函数与作用域 从名字查找先于类型检查我们可以得知为什么基类和派生类中的虚函数为什么必须有相同的形参列表了。...当执行基类的构造函数时,该对象的派生类部分是未被初始化的状态;当执行基类的析构函数时,派生类部分已经被销毁了。

    1.2K20

    面试总结-C++

    用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系;strlen是字符处理的库函数,当数组名作为参数传入时,实际上数组就退化成指针了。。...- 多态性:同一事物表现出不同事物的能力,即向不同对象发送同一消息,不同的对象在接收时会产生不同的行为(重载实现编译时多态,虚函数实现运行时多态)。...静态库则是每次在编译阶段都将静态库文件打包进去,当某个库被多次引用到时,内存中会有多份副本,浪费资源。 2.动态库更新很容易,当库发生变化时,接口没变只需要用新的动态库替换掉就可以。...由于unwind机制的保证,当异常发生时,函数栈内已构造的局部对象的析构函数会被一一调用,在析构函数内释放资源,也就杜绝了内存泄漏的问题。 2.做好程序设计。...7.保证构造、析构、swap不会失败 类型安全 与 线程安全 、异常安全、事务安全 其他 为什么说栈比堆要快 分配和释放:堆在分配和释放时都要调用函数(MALLOC,FREE),比如分配时会到堆空间去寻找足够大小的空间

    2.1K11

    嵌入式软件工程师笔试面试指南-CC++

    修饰函数的返回值。 a.如果给用 const修饰返回值的类型为指针,那么函数返回值(即指针)的内容是不能被修改的,而且这个返回值只能赋给被 const修饰的指针。...初始化和赋值对内置类型的成员没有什么大的区别,像上面的任一个构造函数都可以。但有的时候必须用带有初始化列表的构造函数: 成员类型是没有默认构造函数的类。...因为构造函数没有返回值,所以通知对象的构造失败的唯一方法就是在构造函数中抛出异常。构造函数中抛出异常将导致对象的析构函数不被执行,当对象发生部分构造时,已经构造完毕的子对象将会逆序地被析构。...所以,在程序中,不管对象类型如何转换,该对象内部的虚函数表指针都是固定的,这样才能实现动态地对对象函数进行调用,这就是C++多态性的原理。 纯虚函数指的是什么?...另外,virtual函数是在不同类型的对象产生不同的动作,现在对象还没有产生,如何使用virtual函数来完成你想完成的动作。(这不就是典型的悖论) 3.为什么C++不支持内联成员函数为虚函数?

    1.6K11

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

    this指针的类型是: 类名 *const; 为什么this指针是必须的呢? 1. 可以当做函数的返回类型。 当我们希望一个成员函数的返回类型是对象本身时,可以通过返回this指针来达到这个目的。...具体的做法是取出指针里的内容,用其重新动态申请一片内存存入,然后再赋值给新对象的指针。...当基类包含多个同名成员函数时,派生类重写一个时会把其他的成员函数隐藏掉,这种情况叫做隐藏基类的函数。 比如:我们在mammal中增加两个成员函数。...子类型关系 定义为: 有一个特定的类型S,当且仅当它提供类型T的行为时,成S为类型T的子类型。 共有继承可以实现子类型关系,及派生类是基类的子类型,子类型关系具有传递性但不可逆。...可以看出,我们在构造一个flyhorse对象的时候,发生了五次构造,其中基类被构造了2次,二义性就是从这里产生的。 C++解决这种问题的方法是采用虚基类的方法,也可以称作为虚继承。

    70120

    c++面试题

    (2)使用引用传递函数的参数,在内存中并没有产生实参的副本,它是直接对实参操作;而使用一般变量传递函数的参数,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本;如果传递的是对象,还将调用拷贝构造函数...格式:类型标识符 &函数名(形参列表及类型说明){ //函数体 } 好处:在内存中不产生被返回值的副本;(注意:正是因为这点原因,所以返回一个局部变量的引用是不可取的。...赋值操作符=。这个操作符象流操作符一样,是可以连续使用的,例如:x = j = 10;或者(x=10)=100;赋值操作符的返回值必须是一个左值,以便可以被继续赋值。...此外,就是上面提到的对函数传ref和pointer的区别。 15.什么时候需要“引用”? 流操作符>、赋值操作符=的返回值、拷贝构造函数的参数、赋值操作符=的参数、其它情况都推荐使用引用。...当子类重新定义了父类的虚函数后,父类指针根据赋给它的不同的子类指针,动态的调用属于子类的该函数,这样的函数调用在编译期间是无法确定的(调用的子类的虚函数的地址无法给出)。

    1.2K21

    扫码

    添加站长 进交流群

    领取专属 10元无门槛券

    手把手带您无忧上云

    扫码加入开发者社群

    相关资讯

    热门标签

    活动推荐

      运营活动

      活动名称
      广告关闭
      领券