鱼C论坛

 找回密码
 立即注册
查看: 2589|回复: 0

[见证历程] c到c++过度 第4天

[复制链接]
发表于 2018-4-27 15:00:20 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 代号3 于 2018-4-30 11:40 编辑



多态 模版

数组中保存不同类型的对象:在多个类之上增加一个父类 数组使用父类的类型
后遗症:
        数据保存不完整 高精度赋值给低精度精度丢失
                        解决:不保存完整对象 保存对象的地址 指针数组
                       
        父类通过数组元素调用成员函数时不能调用子类成员函数
                        解决:创建虚函数 前边加virtual (类型前) 父类中函数声明为虚函数
                       
多态
                        对相同的指令做出不同的应答
                       
        实现       
                静态联编        (早期联编)                        默认方式
                        重载
                        重定义
                                都会在编译阶段确定具体使用怎样的应答(函数体)来回应指令(函数调用)
               
                动态联编          多态基础(晚期联编)                                            ?静态地位//有多即动 非多即静
                        特定场合调用虚函数
                        父类指针调用虚函数的时候能够动态识别出指针指向类型,自动指向该类型同名       
                成员函数
                       
                        触发
                                必须被调用函数为虚函数 否则默认静态联编
                                使用父类指针指向子类对象
                                使用父类指针调用虚函数
                        eg:
                       
  1. class Animal{};
  2.                                 calss Dog:public Animal{};
  3.                                 int main
  4.                                 {
  5.                                                         Animal aniObj;
  6.                                                         Dog         dogObj;
  7.                                                         Animal *pAni=nullptr;
  8.                                                         Dog*pDog=nullptr;
  9.                                                        
  10.                                                         aniObj.sound();//不会触发 调用Animal类的函数
  11.                                                         dofObj.sound();
  12.                                                        
  13.                                                         pAni=&anObj;
  14.                                                         pAni->sound();//不会触发 调用Animal类的函数
  15.                                                        
  16.                                                         pDog=&dogObj;
  17.                                                         pDog->sound();//不会触发 调用Dog类函数
  18.                                                        
  19.                                                         pAni=&dogObj;
  20.                                                         pAni->sound();//会触发 调用Dog类函数  此时调用函数为虚函数 父类指针指向子类对象
  21.                                 }
复制代码

                                                                                       
                               
        多态原理
                       
                        动态联编之后 父类指针如何识别出指针指向哪个子类对象                                        ?重载// 满足重写才能实现重载
                       
                        虚函数表
                                当一个类有一个及以上的虚函数时 这个类定义出的对象大小会增加4个字节
                                (在对象的首地址处 内容为地址(虚函数表))
                       
                        地址(虚函数表)储存的是一个数组
                        数组内存档地址(内容为子类对象的函数地址)) 此时就可以调用子类对象中的函数
                       
                        增加虚函数的时候 虚函数列表增加                                                                        ?指针移位实现//编译器自主决定               
                        //虚函数表只有一个  内容可多个(重编译解决数组大小问题) 虚函数可以多个
                       
                        子类重新实现一个虚函数 虚函数表保存的是子类的虚函数地址(子类作为父类时实现多态)               
                        几个 重写?还是另写// 全部刷新 父类被覆盖 不能再被使用
                       
                        子类没有重新实现虚函数 虚函数表保存的是父类的地址
                       
虚函数

        定义
                virtual+基类中的成员函数  编译器会认为该成员函数可能在派生类中存在不同的实现版本
                使用       
                       
                        基类中的函数说明为虚函数
                       
                        定义基类的公有类派生                           基类的公有派生类中重写虚函数(基虚子皆虚)
                       
                        重写虚函数不是重载函数  要求全部相同
                        基类派生重写可以省略virtual
       
        功能
                        允许函数调用与函数体的联系在运行时才动态给出
       
        原理
                        指针保存不同对象

        限制条件
               
                类的成员函数才能说明为虚函数 虚函数仅适用与有继承关系的类对象
               
                静态成员函数不能是虚函数 无法构成重写
               
                正常一个子类被释放时会主动调用其父类的析构函数
                                使用父类指针指向子类对象 当释放该父类指针时 会调用父类的析构函数
                此时子类中若有堆内存的申请 会造成内存泄露(delete基类指针只调用父类的析构函数
                子类不被调用)
                        解决:
                                        将析构函数定义为虚函数(构造函数不能是虚函数 析构可以)                        ?//非唯一 自动调用析构时使用
               
                重载 重定义 重写异同
                                                        作用域                                函数名                                参数
                重载                        相同                                        相同                                        不同                                                overload
                重定义                不同                                        相同                                        相同 /不同                        override
                重写                        不同                                        相同                                        相同                                                overwrite

                重写                                                                                                                                ?实现原理 重定义?//虚函数列表实现  动态联编
                        子类虚函数覆盖基类虚函数
                        特征
                                        不同范围(子类与基类)
                                        函数名相同
                                        参数相同
                                        基类函数中必须有virtual关键字
                                       
纯虚函数
        在基类中不对虚函数给出有意义的实现 仅作为统一的编程接口使用 实现留给该基类
        的派生类去做
       
        语法格式
                class <类名>
                {
                        virtual <函数类型 ><函数名>(<参数表>)=0;
                }
               
抽象类

        一个类中定义了纯虚函数(一个或以上) 这个类会变成抽象类
        只能作为基类用
        抽象类不能直接实例化创建(不能声明抽象类对象) 可以声明抽象类的指针和引用
        可使用指向抽象类的指针支持运行时多态性
         继承抽象类必须重写所有虚函数 否则此类仍然是抽象类
        若是子类继承基类抽象类          给出虚函数                                       
        ?//纯虚函数未实现  子类中重写父类虚函数 此时虚函数表为子类

        子类型
               
                特定类型s当且仅当至少提供了类型t的行为s  称 s类型是类型t的子类型
                s可以有新的行为
               
                子类型关系不可逆
               
模板
        函数模板
        类模板                加class
                        限制条件
                                        成员函数在类外定义的时候必须要放在同一个头文件里。加类名
                                        (不能在.cpp中 会报错且不好查找)
                                       
        语法
                        template<参数化类型名表>
                                        <返回类型><函数名>(<参数表>)
                                        {
                                                        函数体
                                        }
                eg:
                template<typename T_Type>
                int fun(T_Type NumA,T_Type NumB,~~~~~~)
                {
                }
                类类型需要加关键字class
                template <class T_Type>
                {}
               

                函数模版是模板的定义 不是函数 定义中使用通用的类型参数
               
                 模板函数是用函数模板实例化的函数,是事实上的函数定义。
       
                模板函数
                                函数名(实参数),当实参数与函数模板参数相匹配的时候,则产生一个重载函数。
                        重载函数与函数模板实现功能相同(函数体定义相同)则成该重载函数为模板函数。

        模板特化(实例化)       
       
                偏特化
                                所有类型的某一种类型的某几项进行特别处理
                普通特化
                                模板所有替换类型的某一类型进行特别处理
                               

427笔记.txt

6.46 KB, 下载次数: 4

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 22:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表