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

C++中函数重载、隐藏、覆盖和重写的区别

3.1定义 派生类中与基类同返回值类型、同名和同参数的虚函数重定义,构成虚函数覆盖,也叫虚函数重写。 关于返回值类型存在一种特殊情况,即协变返回类型(covariant return type)。...如果派生类中定义了一个与基类虚函数同名但参数列表不同的非virtual函数,则此函数是一个普通成员函数(非虚函数),并形成对基类中同名虚函数的隐藏,而非虚函数覆盖(重写)。...《C++高级进阶教程》中认为函数的隐藏与覆盖是两个不同的概念。隐藏是一个静态概念,它代表了标识符之间的一种屏蔽现象,而覆盖则是为了实现动态联编,是一个动态概念。...C++中函数重载隐藏和覆盖的区别,并不难,难就难在没弄清定义,被网上各种说法弄的云里雾里而又没有自己的理解。...关于三者的对比,李健老师在《编写高质量代码:改善C++程序的150个建议》给出了较为详细的总结,如下表所示: 三者 作用域 有无virtual 函数名 形参列表 返回值类型 重载 相同 可有可无 相同

8.3K62

C++中虚拟函数的内存分配机制

因为虚拟函数的地址翻译取决于对象的内存地址,而不取决于数据类型(编译器对函数 调用的合法性检查取决于数据类型)。...原来,如果类中定义了虚拟函数,该类及其派生类 就要生成一张虚函数表,即vtable。而在类的对象地址空间中存储一个该虚函数表的入口, 占4个字节,这个入口地址是在构造对象是由编译器写入的。...有如下C++程序: //#include #include using namespace std; class CMem { public: CMem...,由于对象的内存空间中包含了虚函数表的入口, 编译器能够由这个入口找到适当的虚函数,这个函数的地址不再由数据类型决定了。...到此,虚函数的秘密终于大白于天下了。虚函数是C++语法的重点和难点。

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

    C++设计模式之SFINAE:用来检测类中是否有某个成员函数

    针对类中特定成员函数的检测其实在工作中也可能用到。C++中可以用SFINAE技巧达到这个目的。...属于C++模板编程中的高级技巧,但属于模板元编程中的基本技巧。当然我其实也并不是C++元编程方面的专家,只是搜集过一些常见的实现方式,然后做过一些测试。...在这个过程中,我发现有些常见的SFINAE写法是有问题的,下面探讨一下。 举个例子,我们来check一下C++标准库的类中有没有push_back()成员函数。...has_hello::value << std::endl; std::cout ::value << std::endl; } OK,这个用来检测类中是否有...所谓变种主要是在has的返回值、value的判断方面做改编。也有一定问题,具体大家自己测试吧。

    4.6K20

    C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别

    https://blog.csdn.net/jxq0816/article/details/82625408 1.虚函数(impure virtual)   C++的虚函数主要作用是“运行时多态...; } }; 2.纯虚函数(pure virtual)        C++中包含纯虚函数的类,被称为是“抽象类”。...抽象类不能使用new出对象,只有实现了这个纯虚函数的子类才能new出对象。   C++中的纯虚函数更像是“只提供申明,没有实现”,是对子类的约束,是“接口继承”。   ...C++中的纯虚函数也是一种“运行时多态”。   ...普通函数是父类为子类提供的“强制实现”。   因此,在继承关系中,子类不应该重写父类的普通函数,因为函数的调用至于类对象的字面值有关。

    2K30

    c语言random函数在vc,C++ 中随机函数random函数的使用方法

    C++ 中随机函数random函数的使用方法 一、random函数不是ANSI C标准,不能在gcc,vc等编译器下编译通过。 可改用C++下的rand函数来实现。...1、C++标准函数库提供一随机数生成器rand,返回0-RAND_MAX之间均匀分布的伪随机整数。 RAND_MAX必须至少为32767。rand()函数不接受参数,默认以1为种子(即起始值)。...(但这样便于程序调试) 2、C++中另一函数srand(),可以指定不同的数(无符号整数变元)为种子。但是如果种子相同,伪随机数列也相同。一个办法是让用户输入种子,但是仍然不理想。...通常rand()产生的随机数在每次运行的时候都是与上一次相同的,这是有意这样设计的,是为了便于程序的调试。...三、按要求设置概率 比如要设置一个10%的概率问题,我们可以采取rand()函数来实现,在if条件句判断里,用rand()得到的值%一个设定的值,再与另一个值做“==”运算。

    5.7K20

    【C++】仿函数在模板中的应用——【默认模板实参】详解(n)

    一.引入:查看(容器)文档时常常遇到的场景 我们在https://cplusplus.com/reference/forward_list/forward_list/查看类模板时,常常会看到这些东西,...其实我们在学习函数参数时也知道默认实参,但在类模板中遇到这种往往犯迷糊;我们直接给出结论:allocator是一个仿函数默认模板实参 二.默认模板实参详解(含代码演示) 前置知识: 仿函数...:把一个类用()重载(类中实现一个operator()),让其能够实现函数的功能 我们可以举一个例子:我们重写 compare,默认使用标准库的 less 函数对象模板 // compare 有一个默认模板实参...: 我们为此模板参数提供了默认模板实参less并为其对应的函数参数也提供了默认实参T 默认模板实参指出:compare 将使用标准库的 less 函数对象类(即仿函数),它是使用与 compare...一的类型参数实例化的 默认函数实参指出f将是类型E的一个默认初始化的对象 当用户调用这个版本的 compare 时,可以提供自己的比较操作,但这并不是必需的 与函数默认实参一样,对于一个模板参数,只有当它右侧的所有参数都有默认实参时

    13310

    Linux+Windows: 程序崩溃时,在 C++ 代码中,如何获取函数调用栈信息

    一、前言 二、Linux 平台 三、Windwos 平台 一、前言 程序在执行过程中 crash 是非常严重的问题,一般都应该在测试阶段排除掉这些问题,但是总会有漏网之鱼被带到 release 阶段。...因此,程序的日志系统需要侦测这种情况,在代码崩溃的时候获取函数调用栈信息,为 debug 提供有效的信息。...这篇文章的理论知识很少,直接分享 2 段代码:在 Linux 和 Windows 这 2 个平台上,如何用 C++ 来捕获函数调用栈里的信息。 二、Linux 平台 1....} 三、Windwos 平台 在 Windows 平台下的代码实现,参考了国外某个老兄的代码,如下: 1....,从地址转换为函数名称。

    5.9K20

    C++ 虚函数详解:多态性实现原理及其在面向对象编程中的应用

    在面向对象的编程中,多态性是一个非常重要的概念。多态性意味着在不同的上下文中使用同一对象时,可以产生不同的行为。...C++是一种面向对象的编程语言,在C++中,虚函数是实现多态性的关键 什么是虚函数 虚函数是一个在基类中声明的函数,它可以被子类重写并提供不同的实现。...在C++中,使用关键字virtual来声明一个虚函数。虚函数的原理是将函数调用的控制权交给运行时环境,而不是编译时环境。因此,虚函数的实现需要在运行时才能确定。...注意,在Circle类中的重写函数中使用了override关键字,这是C++11中引入的新特性,表示该函数是对基类中同名函数的重写。...这种行为称为运行时多态性,因为实际调用的函数是在运行时确定的。 多态的底层原理 在C++中,多态是通过虚函数表和虚指针来实现的。虚函数表是一个特殊的表格,其中包含了虚函数的地址。

    1.1K10

    Java面试中最常见的10个问题,Java底层知识,花点时间学习一下

    Java 中是否可以覆盖(override)一个 private 或者 是static 的方法? “static”关键字表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。...4.是否可以在 static 环境中访问非 static 变量? static 变量在 Java 中是属于类的,它在所有的实例中的值是一样的。...与此相对,方法覆盖是说子类重新定义了父类的方法。方法覆盖必须有相同的方法名,参数列表和返回类型。覆盖者可能不会限制它所覆盖的方法的访问。 7.Java 中,什么是构造函数?什么是构造函数重载?...什么是复制构造函数? 当新对象被创建的时候,构造函数会被调用。每一个类都有构造函数。在程序员没有给类提供构造函数的情况下,Java 编译器会为这个类创建一个默认的构造函数。...Java 不支持像 C++中那样的复制构造函数,这个不同点是因为如果你不自己写构造函数的情况下,Java 不会创建默认的复制构造函数。 8.Java 支持多继承么? 不支持,Java 不支持多继承。

    97650

    【C++】构造函数分类 ② ( 在不同的内存中创建类的实例对象 | 栈内存中创建实例对象 | new 关键字创建对象 )

    一、在不同的内存中创建类的实例对象 1、栈内存中创建实例对象 在上一篇博客 【C++】构造函数分类 ① ( 构造函数分类简介 | 无参构造函数 | 有参构造函数 | 拷贝构造函数 | 代码示例 - 三种类型构造函数定义与调用...栈内存中的 变量 Student s1 ; 这些都是在 栈内存 中创建 类的实例对象 的情况 ; // 调用无参构造函数 Student s1; // 打印 Student s1 实例对象值..., 不需要手动销毁 , 在函数的生命周期结束的时候 , 会自动将栈内存中的实例对象销毁 ; 栈内存中 调用 构造函数 创建的 实例对象 , 不需要关注其内存占用 ; 2、堆内存中创建实例对象 在 栈内存..., 栈内存中只占 4 字节的指针变量大小 ; Student* s2; 在 C++ 语言中 , 可以使用 new 关键字 , 调用有参构造函数 , 创建类的 实例对象 ; 在下面的 C++ 代码中 ,...声明并定义了 MyClass 类 , 该类定义了一个有参构造函数 , 接受两个整数作为 构造函数参数 ; 在 main 函数中 , 使用 使用 new 关键字 来调用 有参构造函数 创建 MyClass

    18820

    C#语言和JAVA、C++的对比学习

    在使用的过程中,不自觉的以前用过的语言Java和C++比较,发现了很多有趣的地方。 C#语言如果简单的来和Java以及C++对比,一句话的结论就是:C++的外表,JAVA的心。为什么这么说呢?...在以分层架构、微核架构下构建的复杂类库,这个特性还是很实用的。而C++则只能用名字空间来做编码上的提示,JAVA则更简单,只有“默认”权限控制符friendly标志,表示包内可访问。...C#在虚方法方面,采用了override和virtual机制,不过需要注意的是,对于interface来说,其覆盖方法只能用override而不能用virtual,而基类如果有virtual方法,其覆盖方法则必须用...JAVA的构造函数继承一直是一个笑话,因为如果你在子类的构造函数中,调用了父类的某个特殊形态的构造函数,这个调用实际上不是在你的代码所在的地方运行的!这简直是对程序代码的欺骗。...在C++里面我们往往会用一些看起来是函数调用的yield()来做goto的事情,实在是被迫无奈。

    1.8K40

    C++11显式虚函数重载:override与final

    场景 在传统C++中,经常容易发现意外重载虚函数的事情: struct Base { virtual void foo(); }; struct SubClass: Base { void...这会带来一个问题:如果我们本来希望派生类可以覆盖掉基类中的虚函数,但是一不小心把形参列表写错了,这可能与我们的本意不符。...C++11新标准提供了override关键字来显式地告知虚拟器进行重载,编译器将检查基类是否存在这样的虚函数,否则将无法通过编译。...这样的好处是使得程序员的意图更加清晰(覆盖基类中的虚函数),如果我们使用override关键字标记了某个函数但是该函数没有覆盖已有的虚函数,此时编译器会报错。...}; final 我们可以把类中的某个函数指定为final,之后任何尝试覆盖该函数的操作都会引发错误,用于防止类被继续继承或者终止虚函数继续重载。

    1.4K30

    深入解析Java对象和类在HotSpot VM内部的具体实现

    Java对象在虚拟机表示中除了字段外还有个对象头,里面有一个字段记录了对象的GC年龄、hash值等信息,这个字段被命名为markOop。...对象 虚拟机中的对象由oop表示。...,这时只能通过基址+偏移×缩放(scale)才能定位堆中任意对象。...图3-5 使用jhsdb hsdb命令可视化查看klass InstanceKlass在虚拟机层描述大部分的Java类,但有少部分Java类有特殊语意:普通类的对象在垃圾回收过程中只需要遍历所有实例字段...在调用虚方法时虚拟机会在运行时常量池中查找n的静态类型Node的print方法,获取它在Node虚表中的index,接着用index定位动态类型AddNode虚表中的虚方法进行调用。

    75640

    JAVA和C++对比学习

    如果有const修饰符就不需要靠人工来遵守了 2.2 默认参数 C++可以在声明函数时添加参数的默认值 JAVA没有办法添加默认值,只能通过方法重载,声明一堆不同参数数量的同名函数来实现 让用户可以用尽量少的参数来调用函数...+可以自由选择在堆还是栈上申请内存(变量),栈上的变量会被自动回收,而且会自动调用析构函数,在堆上申请的变量,使用delete来回收内存以及调用析构函数 JAVA所有类对象只能new在堆上,不需要手动回收...+使用指针或引用来实现动态绑定 C++需要额外注意需要动态绑定的时候,使用的是否引用和虚函数。...权限的内容 4.5 构造器 C++有初始化列表,可以在其中选择不同的基类构造函数 JAVA在子类构造器中假模假样的调用一下选择的基类构造器,实际上那行代码并非在那个时间被调用 JAVA缺乏明确的初始化个成员以及自己的语法...,需要非常注意各属性的初始化写法,以防出现null句柄成员 4.6 反射 C++只能在运行时获取类型名字,无法进行进一步操作 用宏或者存储工厂函数指针的方法来实现反射,虽然麻烦但是也只能这样了

    2.7K40

    C++和java多态的区别

    我们先来看一下在C++中的函数调用方式: Ø 普通函数调用:具体调用哪个方法在编译时间就可以决定(通过查找编译器的符号表),同时在使用标准过程调用机制基础上增加一个表示对象身份的指针(this指针)。...Ø 虚函数调用:函数调用依赖于对象的实际类型,一般地说,对象的实际类型只能在运行时间才能确定。...在Java中的函数调用方式: 区别还是满大的。...在java虚拟机中,类实例的引用就是指向一个句柄(handle)的指针,而该句柄(handle)其实是一对指针:其中一个指针指向一张表,该表格包含了对象的方法列表以及一个指向类对象(表示对象类型)的指针...而C++中只有在构造完毕后(所有的构造函数都被成功调用)才存在,其函数表和对象的实际类型才会确定。所以这两个例子的执行结果会不一样。

    95710

    Java中finalize()用法

    因为这一双重支持,C++ 也提供了自动构造和析构,这导致了对构造函数和析构函数的调用,(对于堆对象)就是内存的分配和释放。 在 Java 中,所有对象都驻留在堆内存,因此局部对象就不存在。...在 Java 中,当你创建一个对象时,Java 虚拟机(JVM)为该对象分配内存、调用构造函数并开始跟踪你使用的对象。...如果finalize() 不是析构函数,JVM 不一定会调用它,你可能会疑惑它是否在任何情况下都有好处。事实上,在 Java 1.0 中它并没有太多的优点。...将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。 ...值得C++程序员注意的是,finalize()方法并不能等同与析构函数。Java中是没有析构函数的。C++的析构函数是在对象消亡时运行的。

    2.5K30

    【C++】多态(上)

    一、多态的概念 用大白话讲就是完成某个行为,不同对象去完成会产生不同状态,C++多态就是在不同继承关系的类对象,去调用同一函数,产生了不同的行为 二、多态的定义以及实现 1、多态的构成条件 必须通过基类的指针或者引用调用虚函数...,当然这其实是一个设计失误,这个多态或者说继承的概念是在析构函数的概念之后产生的,所以作为第一个面向对象的语言,就只能通过打补丁,也就是编译器将两个析构函数转化为destructor()保证它们同名 4...override用来检查派生类虚函数是否重写了基类某个虚函数,如果没有重写编译报错 5、重载、重写、隐藏的对比 重写也叫覆盖,隐藏也叫重定义 三、抽象类 1、概念 在虚函数的后面写上 =0 ,则这个函数为纯虚函数...Func1,所以虚函数的重写也叫作覆盖,覆盖就是指虚表中虚函数的覆盖,重写是语法的叫法,覆盖是原理层的叫法 另外Func2继承下来后是虚函数,所以放进了虚表,Func3也继承下来了,但是不是虚函数,所以不会放进虚表...,用派生类自己的虚函数覆盖虚表中基类的虚函数 c.派生类自己新增加的虚函数按其在派生类中的声明次序增加到派生类虚表的最后 注意虚表存的是虚函数指针,不是虚函数,虚函数和普通函数一样的,都是存在代码段的

    8610
    领券