多态知识点
多态知识点总结如下:
<1> 含有纯虚函数的类称为抽象类
<2> 抽象类不可以实现实例化
<3> 继承抽象类的函数如果没有实现所有的纯虚函数也为抽象类
<4> 纯虚函数的实现格式:virtual void print() = 0;
<5> 继承类在实现纯虚函数时,可以略去关键字virtual,但一般建议必写(便于维护)
<6> 一个虚函数定义在类的内部,但它却不是内联函数
<7> 静态成员函数不可以定义为虚函数
<8> 内联函数不可以定义为虚函数
<9> 常函数可以定义为虚函数
<10> C++运行时多态是通过继承和虚函数实现的
<11> 父类继承子类后:不论是数据成员,还是函数成员,除构造函数与析构函数外全盘接收
<12> 同名覆盖:声明一个和某父类成员同名的新成员,子类中的新成员就屏蔽了基类同名成员
<13> 派生类必须要重写构造函数与析构函数
<14> 一个基类可以直接派生出多个派生类
<15> 多重继承:派生类可以由多个基类共同派生出来
<16> 公有派生是绝对主流
<17> 调用基类构造函数,按它们在派生类定义的先后顺序,顺序调用
<18> 调用成员对象的构造函数,按它们在类定义中声明的先后顺序,顺序调用
<19> 如果基类定义了带有形参表的构造函数时,派生类就应当定义构造函数
<20> 继承的关键是子类继承来一个父类的隐藏对象
<21> 如果基类没有定义构造函数,则派生类也可以不定义,全部采用系统缺省构造函数
<22> 在派生类构造函数中,只要基类不是使用缺省构造函数都要显式给出基类名和参数表
<23> 解决菱形继承的技术是采用虚基类继承
<24> 派生类对象的创建顺序:首先是虚基类的构造函数按它们声明的顺序构造;第二批是非虚基类的构造函数按它们声明的顺序调用;第三批是成员对象的构造函数;最后是派生类自己的构造函数被调用
<25> 派生类析构函数首先对新增一般成员析构,然后对新增对象成员析构,最后对基类成员析构
<26> 赋值兼容规则:任何需要基类对象的地方都可以用公有派生类的对象来代替(切片现象)
<27> 派生类的对象可以赋值给基类的对象,实质是把派生类对象中从对应基类中继承来的隐藏对象赋值给基类对象,反之不可
<28> 可以将一个派生类的对象的地址赋给其基类的指针变量,但只能通过这个指针访问派生类中由基类继承来的隐藏对象,不能访问派生类中的新成员,反之不可
<29> 派生类对象可以初始化基类的引用,但这个别名只能包含派生类对象中的由基类继承来的那个隐藏对象
<30> 虚继承只要在继承时的父类名前加virtual关键字即可
class Student : virtual public Person { ... };
<31> 编译时的多态性:通过函数的重载和运算符的重载来实现的
<32> virtual仅用于类定义中,如虚函数在类外定义,不可加virtual
<33> 当某一个类的某一个成员函数被定义为虚函数后,由该类派生出来的所有派生类中,该函数始终保持虚函数的特征
<34> 重新定义虚函数必须要“三同”准则
<35> 同名覆盖:派生类对一个基类的一般成员函数的重写
<36> 超载:在派生类中重新定义基类的虚函数
<37> 重载:派生类对一个基类的一般成员函数参数有改动后的重写
<38> 派生类采用继承方法,成员对象是嵌套的概念
<39> 某些应用中,对象成员可以代替继承中的基类隐藏对象
<40> 基类在派生类中只能继承一个(间接基类不在讨论之中)不能同时安排两个
<41> 利用多态性技术,可以调用同一个函数名的函数,实现完全不同的功能
<42> 基类中返回基类指针,派生类中返回派生类指针是允许的,这是一个例外
<43> 只有类的成员函数才能声明为虚函数。这是因为虚函数仅适用于有继承关系的类对象
<44> 静态成员函数,是所有同一类对象共有,不受限于某个对象,不能作为虚函数
<45> 一个类对象的静态和动态类型是相同的,实现动态多态性条件:必须使用基类类型的指针变量或引用,使基类指针指向不同派生类的对象,并通过该指针指向虚函数。或者用基类类型的引用调用派生类的中与基类同名的虚函数。才能实现动态的多态性。
<46> 内联函数每个对象一个拷贝,无映射关系,不能作为虚函数
<47> 析构函数可定义为虚函数,构造函数不能定义虚函数,因为在调用构造函数时对象还没有完成实例化
<48> 在基类中及其派生类中都动态分配的内存空间时,必须把析构函数定义为虚函数,实现撤消对象时的多态性
<49> 为了实现多态性,每一个派生类中均要保存相应虚函数的入口地址表,函数的调用机制也是间接实现
<50> 如果定义放在类外,virtual只能加在函数声明前面,不能(再)加在函数定义前面
<51> 根据赋值兼容规则可以用基类的指针指向派生类对象,如果由该指针撤销派生类对象,则必须将析构函数说明为虚函数,实现多态性,自动调用派生类析构函数
<52> 纯虚函数不能调用
<53> 定义纯虚函数时,不能定义纯虚函数的实现部分。即使是函数体为空也不可以
<54> “=0”表明程序员将不定义该函数,函数声明是为派生类保留一个位置
<55> “=0”本质上是将指向函数体的指针定为NULL
<56> 抽象类中的析构函数也是虚函数,这一点非常重要
<57> 要特别仔细揣摩堆内存的分配与释放,删除一个结点时系统自动调用结点类析构函数释放结点占用的动态内存,而结点释放时系统自动调用数据域类析构函数释放数据类占用的动态内存,
<58> 如果使用对象名和点成员选择运算符“.”引用特定的一个对象来调用虚函数,则被调用的虚函数是在编译时确定的(称为静态联编)
<59> 如果使用基类指针或引用指明派生类对象并使用该指针调用虚函数(成员选择符用箭头号“->”),则程序动态地(运行时)选择该派生类的虚函数,称为动态联编
<60> 联编是指计算机程序自身彼此关联的过程,是把一个标识符名和一个存储地址联系在一起的过程,也就是把一条消息和一个对象的操作相结合的过程
<61> 类中只要有且仅有一个虚函数(包括纯虚函数),那么类的sizeof值多四个字节
<62> C++编译器编译含有一个或几个虚函数的类及其派生类时,对该类建立虚函数表(多的四个字节即为虚函数表指针)。
Good Good Study, Day Day Up.
顺序 选择 循环 总结