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

【C++】多态 ⑩ ( 不建议所有函数都声明为 virtual 虚函数 | 多态理解层次 | 父指针子类指针步长 )

对象可以直接获取到自身封装 普通函数 , 如果要访问函数 , 需要增加一次寻址操作 , 因此 这里建议不需要将有 多态 需求函数明为函数 ; C++ 中 指向某类型对象 指针 运算 ,...没有添加任何 成员函数成员方法 , 那么子类指针 与 父指针 步长是相同 ; 一、不建议所有函数都声明为 virtual 虚函数 C++ 中 , 每个 成员函数 都可以声明为 virtual...这里建议不需要将有 多态 需求函数明为函数 ; 二、多态理解层次 多态理解层次 : 多态实现效果 : 相同代码调用 , 有不同表现形态 ; 父指针指向子类对象 , 使用指针...调用 虚函数 可执行 子类对应函数 ; 多态实现条件 : ① 继承 , ② 虚函数重写 , ③ 父指针/引用指向子类对象 ; 父指针 可以 指向对象 , 也可以指向 不同 子类对象 ;...; 有 虚函数 , 编译 , 会生成 虚函数表 , 对应中生成一个 vptr 指针指向函数表 ; vptr 指针 是 与 对象绑定 , 调用时 从 对象函数表 中查找虚函数

21550

【C++】继承 ⑥ ( 继承构造函数析构函数 | 类型兼容性原则 | 父指针 指向 子类对象 | 使用 子类对象 为 父对象 进行初始化 )

地方 , 都可以使用 " 公有继承 " 派生 ( 子类 ) 对象 替代 , 该 派生 ( 子类 ) 得到了 除 构造函数 析构函数 之外 所有 成员变量 成员方法 ; 功能完整性 :..." 公有继承 " 派生 ( 子类 ) 本质上 具有 基 ( 父 ) 完整功能 , 使用 可以解决问题 , 使用 公有继承派生 都能解决 ; 特别注意 : " 保护继承 " ..." 私有继承 " 派生 , 是 不具有 基 完整功能 , 因为 最终继承派生 , 无法 外部调用 父 公有成员 保护成员 ; 2、类型兼容性原则应用场景 " 类型兼容性原则..." 应用场景 : 直接使用 : 使用 子类对象 作为 父对象 使用 ; 赋值 : 子类对象 赋值给 父对象 ; 初始化 : 使用 子类对象 为 父对象 初始化 ; 指针 : 父指针 指向...子类对象 , 父指针 值为 子类对象 堆内存 地址 , 也就是 子类对象 地址 赋值给 父类型指针 ; 引用 : 父引用 引用 子类对象 , 子类对象 赋值给 父类型引用 ; 二

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

C++之面向对象三个基本特征

运算符重载函数作为 成员函数 与 友元函数(形参必须有要求) 一般单目运算符复合运算符重载为成员函数 一般双目运算符重载为友元函数;   重载双目运算符 C++构造函数重载 一个中可以定义多个构造函数...虚函数作用是允许派生中重新定义与基类同名函数,并且可以通过基指针或引用来访问派生同名函数。...通过该指针变量调用此虚函数,此时调用就是指针变量指向对象同名函数。 通过虚函数指向对象指针变量配合使用,就能方便地调用同一族中不同类同名函数,只要先用基指针指向即可。...3)应考虑对成员函数调用是通过对象名还是通过基指针或引用去访问,如果通过基指针或引用去访问,则应当声明为函数; 4)有时,定义虚函数,并不定义其函数,即函数体是空。...通常来说,如果基中存在一个指向动态分配内存成员变量,并且基析构函数中定义了释放该动态分配内存代码,那么就应该析构函数明为函数

1.1K60

《Effective C++》读书摘要

七、多态声明虚析构函数 (不)具有多态性质基(不)需要虚析构函数; 八、不让异常逃出析构 异常终止或者吞下; 将可能抛出异常代码提供给用户管理; 九、不在构造析构中调用虚函数 调用后仅仅是自身函数...二十三、用非成员函数非友元函数替换成员函数 封装强度改变强度成反比,因为只影响有限用户; 访问函数封装性好于累内成员函数封装性,不增加累内私有数据访问函数数量; 二十四、参数需要类型转换应使用成员函数...使得不同功能通过继承HealthCalcFunc改变。 三十六、绝不定义继承非虚函数 重修继承非虚函数导致函数访问指向对象指针或引用类型决定。...三十七、绝不定义继承默认参数值 重载函数默认参数来自于基默认参数函数明为普通成员函数,调用私有的虚函数即可。...四十六、类型转换为模板定义非成员函数 对于模板化要支持双操作运算符重载,首先必须是非成员函数,另外为了能让模板具体化必须将函数定在体内部,因此只能将之声明为友元类型。

1.9K60

C++基础(七).多态(1)

《C++ 虚函数&纯虚函数&抽象&接口&虚基》 《C++抽象基纯虚函数》 ---- 概要 ---- 多态 面向对象语言中,接口多种不同实现方式即为多态 多态特性中,可以子类类型指针赋值给父类型指针...;可以用父指针指向子类实例(对象),然后通过父指针调用实际子类成员函数 多态是通过虚函数实现 多态可以让父指针有“多种形态”,这是一种泛型技术(所谓泛型技术,就是试图使用不变代码来实现可变算法...如果在派生中没有对虚函数重新定义,则它继承其基函数函数可以让成员函数操作一般化,用基指针指向不同派生对象,基成员函数调用基指针,则会调用其真正指向对象成员函数,而不是基中定义成员函数...里声明为函数的话,这个函数是实现,哪怕是空实现,它作用就是为了能让这个函数子类里面可以被重载,这样的话,编译器就可以使用后期绑定来达到多态了,纯虚函数只是一个接口,是个函数声明而已,它要留到子类里去实现...抽象是不能定义对象实际中为了强调一个是抽象,可将该类构造函数明为保护访问控制权限 抽象主要作用是将有关组织一个继承层次结构中,由它来为它们提供一个公共根,相关子类是从这个根派生出来

46820

适合具备 C 语言基础 C++ 教程(七)

前言 在前面的教程中,阐述了继承相关内容,其中就包括继承之后数据成员访问控制以及多重继承,虚拟继承等内容,本节内容即将阐述另外一个面向对象特性:多态多态是面向对象编程三大特性之一。...实现里,成员函数前面加了virtual关键字,则将eating函数就变成了虚函数,Humaneating方法变成了虚函数,那么EnglishManchineseeating方法也变成了虚函数...只有成员函数才能做为虚函数; 静态成员函数不能是虚函数; 内联函数不能是虚函数; 构造函数不能是虚函数; 析构函数一般都声明为函数; 作为析构函数一般都声明为函数,我们以代码详细阐述一下,首先...,因此也就证实了那句话析构函数一般声明为函数,更改之后代码如下所示: 析构函数改为虚函数之后,我们继续运行主函数内容,运行结果如下所示: 通过上述可以看到,执行析构函数也根据不同实例化对象...,否则不可以设置为虚函数,我们使用代码来具体阐述,同样,我们先编写各个代码实现: 上述代码中,可见每个 test()函数返回值分别是各个指针,形参为void,这也满足了返回值不同,形参相同可以作为虚函数条件

43810

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

具体来说,多态性允许基指针或引用在运行时指向派生对象,并且根据对象实际类型来调用相应成员函数多态性是通过虚函数来实现。...当一个基成员函数被声明为函数,派生可以通过覆盖(重写)这个函数来提供自己实现。在运行时,调用这个虚函数时候,实际上调用指向对象实际类型版本。...动态多态(运行时多态): 主要是通过虚函数继承实现,例如,基指针指向派生对象,并调用虚函数。在运行时,根据对象实际类型来决定调用哪个版本函数。这种多态性在运行时才会确定。...动态多态性通过虚函数继承来实现,在编译无法确定函数调用具体版本,而是在运行时根据对象类型动态确定。...方法调用 C++ 中,如果父通过指针或引用调用一个虚函数,而这个虚函数子类中被重写(override),那么调用实际方法取决于指针或引用所指向对象类型。这就是多态体现。

10310

C++基础-多态

这种情况未启用多态机制 如果基 Swim() 是虚函数,那么运行时会根据基引用(或指针)指向具体对象,调用对象所属方法。...这种情况使用多态机制 使用指针或引用指向或派生对象,运行时调用对象所属(具有继承层次关系或派生)中方法,这就是多态。...如果不将析构函数明为函数,那么如果一个函数形参是基指针,实参是指向堆内存派生指针函数返回作为实参派生指针将被当作基指针进行析构,这会导致资源释放不完全内存泄漏;要避免这一问题,...普通函数不支持多态,所以需要继承函数应声明为函数,不应使用普通函数 5. 使用继承解决菱形问题 一个继承多个父,而这多个父继承一个更高层次,会引发菱形问题。...可见使用继承可以解决多继承菱形问题,确保 继承层次结构中,继承多个从同一个派生而来,如果这些基没有采用虚继承导致二义性。

83220

派生多态函数

当我们使用指针或引用调用虚函数,该调用将被动态绑定。...成员函数如果没被声明为函数,则其解析过程发生在编译时而非运行时。就会按照实际情况调用。 派生可以继承定义成员,但是派生成员函数不一定有权访问从基继承而来成员。...其他使用代码一样,派生访问公有成员,而不能访问私有成员。 不过某些时候基中还有这样一种成员,基希望它派生有权访问成员,同时禁止其他用户访问。...如果派生没有覆盖其基某个虚函数,则该虚函数行为类似于其他普通成员,派生会直接继承版本,派生可以它覆盖函数使用virtual关键字,但不是非得这么做(可有可无)。...晚绑定-》运行阶段确定函数地址 动态多态满足关系: 1.有继承关系 2.子类重写父函数 动态多态使用:父指针或引用 指向子类对象 重写:函数返回值类型 函数名 参数列表 完全一致叫重写

14720

封装、继承多态、重载:C++中强大特性与代码设计

通常将公有成员函数作为接口,供外部使用。 private(私有)访问修饰符成员隐藏在内部,外部无法直接访问私有成员变量私有成员函数。通常将私有成员用于实现内部逻辑。...当通过指向指针或引用调用虚函数根据实际对象类型来选择正确函数实现。这种动态选择函数机制称为动态绑定(dynamic binding)。虚函数通过关键字virtual进行声明。...main函数中,我们使用指向指针shapePtr来处理不同类型对象。...只有通过基指针或引用调用虚函数才能引发动态绑定 虚函数不能声明为静态 如果一个要做为多态,要将析构函数定义为虚函数 虚表指针函数动态绑定是通过虚表来实现 包含虚函数头4个字节存放指向虚表指针...对于暂时无法实现函数,可以声明为纯虚函数,留给派生去实现 注意: 抽象只能作为基使用 不能声明抽象对象,可以使用抽象指针引用 构造函数不能是虚函数,析构函数可以是虚函数 可以试用指向抽象指针支持运行时多态

19010

适合具备 C 语言基础 C++ 入门教程(七)

前言 在前面的教程中,阐述了继承相关内容,其中就包括继承之后数据成员访问控制以及多重继承,虚拟继承等内容,本节内容即将阐述另外一个面向对象特性:多态多态是面向对象编程三大特性之一。...代码实现 上述用通俗的话解释了一下,那么现在我们编写具体代码来实现一下,上述中有人类,有英国人,有中国人,那么我们定义一个Human,然后 EnglishManChinese都继承自Human,代码如下所示...,成员函数前面加了virtual关键字,则将eating函数就变成了虚函数,Humaneating方法变成了虚函数,那么EnglishManchineseeating方法也变成了虚函数。...简而言之,也就是说一个里有虚函数,那么这个实例化对象中必然存在指针指针指向函数表,通过指针指向函数表调用虚函数,下面是这个过程一个示意图: [image-20210220111846577...除了上述所说到这个点以外,作为多态还有其他几个限制,分别是: 只有成员函数才能做为虚函数; 静态成员函数不能是虚函数; 内联函数不能是虚函数; 构造函数不能是虚函数; 析构函数一般都声明为函数

34200

C++虚函数

函数是动态多态基础,其调用方式是动态联编(又称晚期联编,简单解释为只有程序运行时才决定调用基还是子类,系统会根据基指针指向对象来决定要调用函数); 非虚函数与其相反,...通过虚函数指向对象指针变量配合使用,就能方便地调用同一同名函数,只要先用基指针指向即可。     如果指针不断地指向同一族中不同类对象,就能不断地调用这些对象中同名函数。...什么时候应该把一个成员函数明为函数呢? (1)首先看成员函数所在是否会作为基。然后看成员函数继承后有无可能被更改功能,如果希望更改其功能,一般应该讲其声明为函数。...(2)如果成员函数继承后功能不需要修改,或派生用不到该函数,则不要把它声明为函数。...(3)应该考虑成员函数调用是通过对象名还是通过基指针或引用去访问,如果是通过基指针或引用去访问,则应当什么为虚函数。 (4)有时定义虚函数,并不定义其函数体,即函数体是空

1.1K30

函数&多态

对于经常被问到函数多态问题,发现百度百科回答得十分详细,所以自己百度百科上解释进行总结 一、虚函数 (1)虚函数简介:某基中声明为virtual并在一个或者多个派生中被重新定义成员函数...;实现多态性,通过指向派生指针或引用,访问派生中同名覆盖成员函数。...(6)总结: 指向指针操作它多态对象,会根据不同对象,调用其相应函数,这个函数就是虚函数; 虚函数联系到多态多态联系到继承。 二、多态性   多态是指同一个实体同时具有多种形式。...运行时,为动态多态具体引用对象要在运行时才能确定; 编译,为静态多态,在编译就可以确认对象使用形式。 (1)定义:多态是指同一操作作用于不同对象,可以有不同解释,产生不同执行结果。...使用继承结果就是当创建了一个家族,认识这个家族,就是把子类对象当作基对象,这种认识又叫作upcasting(向上转型)。

1.1K10

深入解析C++中函数继承:实现多态性与继承关系高级特性

这使得继承关系中,通过基指针或引用调用虚函数,可以根据实际对象类型来动态地确定要执行函数版本,实现多态特性。...C++中,当基指针或引用指向派生对象,通过调用虚函数,可以实现对应于派生特定实现。这种根据对象实际类型来确定调用哪个函数机制就是动态绑定。...动态绑定关键在于使用virtual关键字将成员函数明为函数,并在基派生中提供相应实现。...: 1.有继承关系 2.子类重写父函数 动态多态使用:父指针或引用 指向子类对象 重写:函数返回值类型 函数名 参数列表 完全一致叫重写 如果子类中没有堆区数据,可以不用写虚析构纯虚析构...它是实现抽象多态重要机制之一。 如果某个函数不是抽象成员函数,不能用基指针调用。

90410

如何用C语言实现OOP

接下来就需要实现具体函数,再在执行构造函数手动函数指针指向最终实现函数。...但是编译 C 源码,编译器没有这种操作,需要我们手动去调用构造函数析构函数。而且调用 C 构造函数,需要我们手动函数指针指向最终实现函数。... C++ 使用公有继承(没有虚函数),编译器会在编译期间成员变量插入到子类中,通常是按照顺序插入(具体视编译器决定)。...说到这里,我们很容易就能想到如何使用 C 语言实现 C++ 公有继承了(不带虚函数),就是子类中定义一个父成员变量,而且父成员变量只能放在最开始位置。...这个时候函数指针又发挥作用了!我们可以把多个函数指针放在父中,就可以之类构造函数中直接函数指针重新指向实现函数,这就实现了我们想要多态性!

1.2K10

C++【继承

---- 前言 继承 是面向对象三大特性之一(封装、继承多态),所有的面向对象(OO)语言都具备这三个基本特征,封装相关概念已经对象》系列中介绍过了,今天主要学习继承,即如何在父基础之上...构造析构函数设为私有,这样子类就无法创建父对象,同时也就无法继承了 ---- 3、继承作用域 子类虽然继承自父,但两者作用域是不相同,假设出现同名函数,默认会将父同名函数隐藏调...,具体切片实现原理还后续再进行讲解 注意: 切片只 子类->父 发生,因为父无法满足子类需求 ---- 5、派生默认成员函数 派生(子类)也是 ,同样会生成 六个默认成员函数(用户未定义情况下...对于冗余数据位,改存指针,该指针指向相对距离 对于冗余成员,合并为一个,放置后面,假设想使用公共成员(冗余成员),可以通过相对距离(偏移量)进行访问 这样就解决了数据冗余二义性问题 为何在冗余处存指针...指针指向空间有预留一个位置,可以用于多态 因此虚继承是第二个位置 新建对象进行兼容赋值,对象指向指针处 该指针(偏移量)指向目标位置不定 无论最终位置何处,最终汇编指令都一样(得益于偏移量设计模式

13710

深度解读《深度探索C++对象模型》之C++虚函数实现分析(一)

静态成员函数上面提到非静态成员函数调用,必须要经由对象来调用,是因为需要将对象地址作为函数参数,也就是隐式this指针,这样函数访问非静态数据成员绑定到此地址上,也就是将此地址作为基地址...而非静态成员函数,返回是一个“指向成员函数指针”,如上面定义print函数,返回类型是:void (Object::*) ();静态成员函数基本上等同于普通函数,所以C语言结合编程,可以作为回调函数传递给...代码中,一般是声明一个基指针,此指针在运行期间可能指向不同派生,然后通过基指针调用一个接口,这个接口不同派生中有不同实现,所以根据基指针指向哪个具体派生,调用就是这个派生实例...假设有一个名称为print接口,p是基类型指针,那么下面的调用:p->print();是如何识别出要实施多态行为?以及如何调用到具体哪个派生print?...方法就是编译器根据中是否有虚函数,如果有虚函数,就在构造函数里插入一些汇编代码,构造对象,在对象前面插入一个指针,这个指针指向这个虚函数表,所以这个指针也叫做虚函数指针

20220

领悟面向对象就离开发应用不远了(提高)有你对面向对象所有疑问,爆肝1w字

文章目录 前言 一、面向对象 二、使用 1.基础使用 2.运算符重载 3.友元 1.友元函数 2.友元 3.友元成员函数 三、继承 派生 插个访问权限事情 2.多态 ***公有 **...(继承了基实现) 派生继承了基接口 当然派生其他使用方法大致一样:可以有自己构造函数,可以添加额外数据成员成员函数 插个访问权限事情 首先派生不能直接访问私有成员,...下面分别从这两个方面对virtual进行介绍。 虚函数函数源于c++中继承,是多态一种。c++中,一个基指针或者引用可以指向或者引用派生对象。...基中 可以中将被重写成员函数设置为虚函数,其含义是:当通过基指针或者引用调用该成员函数根据指针指向对象类型确定调用函数,而非指针类型。...C++中一般情况下联编是静态联编,但是当涉及到多态函数应该使用动态联编。动态联编优点是灵活性强,但效率低。

50620

C++进阶:详解多态多态、虚函数、抽象以及虚函数原理详解)

通过基指针或引用调用虚函数根据对象实际类型调用相应派生函数 从上面这段话我们知道继承中要构成多态还有两个条件: 必须通过基指针或者引用调用虚函数 被调用函数必须是虚函数...,上面也是一个经典场景——使用多态,通过基指针删除派生对象 2.3C++11里 override final final:用于派生中阻止对虚函数进一步重写,或者定义中阻止被继续派生...所以如果不实现多态,不要把函数定义成虚函数 普通函数继承(实现继承): 普通函数继承中,派生继承了基函数具体实现。 派生可以直接使用函数,而不需要重新实现该函数。...这种继承关系主要关注函数具体行为功能。 虚函数继承(接口继承): 函数继承中,派生继承了基函数接口,即函数声明。...多态必须使用指针/引用来调用虚函数原因主要是因为基指针/引用可以在运行时指向派生对象,而且能正确地调用派生函数

37210

C++基础-对象

面向对象编程有四个重要基础概念:抽象、封装、继承多态。本文整理 C++ 中与对象基础内容,涉及抽象封装两个概念。《C++基础-继承》一文讲述继承概念。《C++基础-多态》一文讲述多态概念。...程序设计中,就是把成员(属性行为)进行整合分类,确定哪些成员是私有的,哪些成员是公共,私有成员隐藏,公共成员开放。用户(调用者)只能访问公共接口。 1....声明构造函数时务必考虑使用关键字 explicit,以避免隐式转换。 务必将成员明为 std::string 智能指针(而不是原始指针),因为它们实现了复制构造函数,可减少您工作量。...4.3 禁止栈中实例化 析构函数明为私有的。略 4.4 使用构造函数进行类型转换 略 5. this 指针 中,关键字 this 包含当前对象地址,换句话说, 其值为&object。...成员方法中调用其他成员方法, 编译器隐式地传递 this 指针。 调用静态方法,不会隐式地传递 this 指针,因为静态函数不与实例相关联,而由所有实例共享。

96220
领券