问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501
你好,欢迎来到懂视!登录注册
当前位置: 首页 - 正文

C++的封装、继承、多态

发布网友 发布时间:2024-10-20 16:10

我来回答

1个回答

热心网友 时间:2024-11-19 23:16

定义:封装就是将抽象对象的属性和行为特征结合,形成类。数据(属性)和函数(行为特征)都是类的成员,目的将对象的使用者和设计者分开,提高软件的可维护性和可修改性。


特性:



结合性,属性和方法结合


隐蔽性,利用接口机制隐蔽内部实现细节,只留接口给外部调用


实现代码的重用



定义:继承就是新类从已有类那里得到已有的特性。类的派生指从已有类产生新类的过程。原有类成为基类或父类,产生的新类称为派生类或子类。


单一继承:继承一个父类,这种继承称为单一继承。一般情况尽量使用单一继承,使用多重继承容易造成混乱易出问题。


多重继承:继承多个父类,类与类之间要用逗号隔开,类名之前要有继承权限,假使两个基类都有某变量,在子类中调用时需要加上类名限定符,例:c.a::i = 1;


菱形继承:多重继承掺杂隔代继承1-n-1模型,此时需要用到虚继承,例如:B、C虚继承于A,D多继承于B、C,否则会出错


继承权限:继承方式指定了子类从父类中继承的成员访问权限


继承可以扩展存在的代码,目的是为了代码复用


继承也分为接口继承和实现继承:



普通成员函数的接口总是会被继承:子类继承一份接口和一份强制实现


普通虚函数被子类重写:子类继承一份接口和一份缺省实现


纯虚函数只能被子类继承接口:子类继承一份接口,没有继承实现



什么是菱形继承?菱形继承:多个类继承了同一个公共基类,而这些派生类又同时被一个类继承。


D的对象模型里面保存了两份base,当我们想要调用从base里继承的fun时就会出现调用不明确问题,造成数据冗余的问题。


如何解决这个问题?



使用域限定我们所需访问的函数


虚继承



让A和B在继承base时加上vritual关键字。


A和B不在保存base内容,而是保存了一份偏地址,将base保存在一个公共位置,保证了数据冗余性降低的同时,也能直接使用d.fun()调用base里的函数。


定义:一个接口,多种实现方式;多态有两种形式:静态多态和动态多态


动态多态:



是指在程序运行时才确定函数和实现的链接,此时才能确定调用哪个函数,父类指针或者引用能够指向子类对象,调用子类函数,所以在编译时无法确定是调用哪个函数。


优点:OO设计重要的特性,对客观世界直觉认识;能够处理同一个继承体系下的异常类集合


缺点:运行期间进行虚函数绑定,提高了程序运行开销;庞大的类继承层次,对接口的修改易影响类继承层次;由于虚函数在运行期才绑定,所以编译器无法对虚函数进行优化



定义:用virtual关键字修饰的函数,本质:由虚函数指针和虚函数表控制某个虚函数入口地址,就实现了多态,作用:实现多态,虚函数可以被子类重写,虚函数地址存储在虚函数表中


虚表:虚表中主要是一个类的虚函数的地址表,这样表解决了继承、覆盖的问题,保证其真实反映实际的函数,当我们用父类指针来指向一个子类对象的时候,虚表指明了实际所调用的函数。基类有一个虚表,可以被子类继承(当类中有虚函数时该类才会虚表,该类的对象才会有虚指针,子类继承时也会继承基类的虚表),子类如果重写了基类的某虚函数,那么子类继承于基类的虚表中该虚函数的地址会相应的改变,指向子类。自身的该虚函数实现,如果子类有自己的虚函数,那么子类的虚表中就会增加该项,编译器为每个类对象定义了一个虚指针,来定位虚表,所以虽然是父类指针指向子类对象,但因为此时子类重写了该虚函数,该虚函数的地址在子类虚表中的地址已经被改变了,所以它实际调用的是子类的重写后的函数


一旦虚指针被初始化为指向相应的虚表,对象就知道他自己是什么类型,但只有当虚函数被调用时这种自我认知才有用。


每一个带有virtual的函数都有一张相应的虚表,当对象调用某一个virtual函数时,实际被调用的函数取决于该对象的虚指针所指向的那个虚表--编译器在其总寻找适当虚函数指针。


效率漏洞:我们必须明白,编译器正在插入隐藏代码到我们的构造函数中,这些隐藏代码不仅必须初始化虚指针,而且必须检查this的值(避免operater new返回0)和调用基类构造函数。放在一起这些代码可以影响我们认为是一个小内联函数的调用,特别是,构造函数的规模会抵消函数调用代价的减少,如果大量的内联函数调用,代码长度就会增长,而在速度上没有任何好处;当然,也许不会立即把所有这些小构造函数都变成非内联,因为它们更容易写为内联构造函数,但是,当我们正在调整我们的代码时,请务必去掉这些内联构造函数。


虚函数时用:将函数声明为虚函数会降低效率,一般函数在编译器其对应地址是确定的,编译器可以直接生成imp/invoke指令,如果是虚函数,那么函数的地址是动态的,譬如取到的地址在eax寄存器里,则在call eax之后的那些已经被预取到流水线的所有指令都将失效,流水线越长,那么一次分支预测失败的代价越大,建议若不打算让某类成为基类,最好不要使用虚函数。


纯虚函数:含有至少一个纯虚虚函数的类叫做抽象类,因为抽象类含有纯虚函数,所以其虚表是不健全的,在虚表不健全的情况下是不能实例化对象的,子类继承抽象类后必须重写父类所有纯虚函数,子类才能实例化对象,纯虚函数只声明不定义。例如:virtual void fun()=0;


静态多态:是在编译器就把函数连接起来,此时即可确定调用那个函数或模板,静态多态是由摸板和重载实现的,在宏多态中,是通过定义变量,编译时直接把变量替换,实现宏多态。


优点:带来了泛型编程的概念,使得C++拥有泛型编程于STL这样的容器;编译器完成多态,提高运行期效率;具有很强的耦合性(两个功能模块之间的依赖关系)


缺点:程序可读性降低,代码调试带来困难;无法实现模板的分离编译;无法处理异质对象集合


调用父类指针创建子类对象,那么父类应该有虚析构函数,因为如果父类没有虚析构函数,那么在删除这个子类对象的时候会调用错误的析构函数而导致删除产生不明确行为

声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。
E-MAIL:11247931@qq.com
古天乐的资料!!! 胆结石可以喝柠檬蜂蜜水吗 柠檬对结石有什么作用 胆结石可以吃柠檬吗 江西有哪些风景 行政处罚对象能不能是分公司 分公司是否能作为被行政处罚的对象 分享20份亚马逊运营过程中常用邮件回复模板 2024年上半年自考报名时间 22年辽宁省自考延期怎么退费 淋了雨吃了龙虾啤酒后开始感冒流鼻涕,过两天开始发烧 ...感觉胃在发烧,有点想拉肚子,可是拉不出来,喝了一瓶牛奶,怎么办... 小孩发烧可以吃小龙虾吗 昨晚吃了油大龙虾儿子半夜就发烧六个月了是龙虾有关吗用什么土方法退烧... 龙之谷法师转职元素好还是魔道好。主要单刷 龙之谷2法师转元素和魔法指引哪个好? 老爸血脂稠 吃什么好? sd是什么均值 脑子血脂稠应该怎么治疗,需要吃什么药调理 ...血脂稠、心脑血管这类疾病,应该吃什么药 打什么针呢? ...师并取得证书是真的假的,我之前没有任何茶艺学习 老人浑身疼是什么原因 浑身酸痛挂什么科 语法题逗号后面的句子主语部分只能指代前面主语,不能指代别的? 并列主语之间用什么标点 ...后面能加句子还是名词还是to do?but后还能不能有主语,but前能... ...very late .这句话中but 的前面要不要有一个逗号啊? dota2无法与任何服务器建立连接怎么办dota2无互联网连接怎么解决 重装win10系统后dota2无法与任何服务器建立连接咋处理 ...实在打不了登进去签到也行,明日之后低画质可以玩吗? 太原哪拍星星比较好,我想拍一组星星或星迹照片,谁能给推荐个好地方呢... 关于孤岛危机中的空中支援 realme欢太账户锁定怎么搞 考C1科目三挂了五次 后一点要去驾校重新报名吗 。可以自考吗_百度知 ... 工商银行汇款时候用的账号是存折上的账号还是牡丹卡上的账号? ...不过从网银里面看到有一个下挂账户是什么意思?它可以用来收款吗... 工商银行牡丹卡是什么意思 中国工商银行 牡丹卡 上的钱为什么凭空少了10几块呢? 大卫 昙花 雷神 仙人掌 碧光环 熊童子哪个不是多肉植物 现在11月气温在15-26度之间,我想种碧光环、熊童子、这类的植物,请问这... 快手红包为什么有的时候有字有的时候没字 发动机油底壳大和小的区别 山西离保定有多远 我想做张20k 130px×160px 大小的照片 该怎么弄 寻求帮助 谢谢... 你好,请问能不能帮我处理一张160px*130px并且小于20k的照片 ...160px,宽为130px.大小不能超过10K,这样的照片怎么调整? 报名的照片又要大于10K小于20K,大小还得是160px * 130px,我快崩溃了... 水干了怎么找甲鱼窝水干了如何找甲鱼窝 冬天甲鱼喜欢躲在池塘的什么地方? 大人国和小人国内容简介
  • 焦点

最新推荐

猜你喜欢

热门推荐