同一种语句有多重形态。在不同的类型中,有不同的属性和表现方法。
多态原理。多态的是函授指针
多态的实现效果
多态:相同的调用语句有多种不同的表现形态;
多态实现的三个条件
有继承、有virtual重写、有父类指针(引用)指向子类对象。
多态的C++实现
virtualkeyword。告诉编译器这个函数要支持多态;不要依据指针类型推断怎样调用;而是要依据指针所指向的实际对象类型来推断怎样调用
多态的理论基础
动态联编PK静态联编。依据实际的对象类型来推断重写函数的调用。
多态的重要意义
设计模式的基础。
实现多态的理论基础
函数指针做函数參数
C++中多态的实现原理
当类中声明虚函数时,编译器会在类中生成一个虚函数表
虚函数表是一个存储类成员函数指针的数据结构
虚函数表是由编译器自己主动生成与维护的
virtual成员函数会被编译器放入虚函数表中
存在虚函数时,每一个对象中都有一个指向虚函数表的指针(vptr指针)
|
|
|
说明1:
通过虚函数表指针VPTR调用重写函数是在程序执行时进行的,因此须要通过寻址操作才干确定真正应该调用的函数。而普通成员函数是在编译时就确定了调用的函数。在效率上,虚函数的效率要低非常多。
说明2:
出于效率考虑,没有必要将全部成员函数都声明为虚函数
|
|
2、构造函数中能调用虚函数,实现多态吗?why?
1)对象中的VPTR指针什么时候被初始化?
对象在创建的时,由编译器对VPTR指针进行初始化
仅仅有当对象的构造全然结束后VPTR的指向才终于确定
父类对象的VPTR指向父类虚函数表
子类对象的VPTR指向子类虚函数表
|
2)分析过程
绘图分析
3)结论:构造函数中调用多态函数,不能实现多态。
|
4)怎样证明vptr指针的存在哪?
|
|
30. 函数重载是什么意思?它与虚函数的概念有什么差别?
答:函数重载是一个同名函数完毕不同的功能,编译系统在编译阶段通过函数參数个数、參数类型不同,函数的返回值来区分该调用哪一个函
数,即实现的是静态的多态性。可是记住:不能只通过函数返回值不同来实现函数重载。而虚函数实现的是在基类中通过使用keywordvirtual
来申明一个函数为虚函数,含义就是该函数的功能可能在将来的派生类中定义或者在基类的基础之上进行扩展,系统仅仅能在执行阶段才干动态
决定该调用哪一个函数,所以实现的是动态的多态性。它体现的是一个纵向的概念,也即在基类和派生类间实现。
45. 虚拟函数与普通成员函数的差别?内联函数和构造函数是否能为虚拟函数?
答案:差别:虚拟函数有virtualkeyword,有虚拟指针和虚函数表,虚拟指针就是虚拟函数的接口,而普通成员函数没有。内联函数和构造函数不能为虚拟函数。
46. 构造函数和析构函数的调用顺序? 析构函数为什么要虚拟?
答案:构造函数的调用顺序:基类构造函数—对象成员构造函数—派生类构造函数;析构函数的调用顺序与构造函数相反。析构函数虚拟是为了防止析构不彻底,造成内存的泄漏。
127.类成员函数的重载、覆盖和隐藏的差别
答案:
成员函数被重载的特征:
(1)同样的范围(在同一个类中);
(2)函数名字同样;
(3)參数不同。
覆盖是指派生类函数覆盖基类函数。特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字同样;
(3)參数同样;
(4)基类函数必须有virtual keyword。
“隐藏”是指派生类的函数屏蔽了与其同名的基类函数,规则例如以下:
(1)假设派生类的函数与基类的函数同名,可是參数不同。此时,不论有无virtualkeyword。基类的函数将被隐藏(注意别与重载混淆)。
(2)假设派生类的函数与基类的函数同名。而且參数也同样,可是基类函数没有virtual keyword。此时,基类的函数被隐藏(注意别与覆盖混淆)
重写PK 重载理解
函数重载
必须在同一个类中进行
子类无法重载父类的函数。父类同名函数将名称覆盖
重载是在编译期间依据參数类型和个数决定函数调用
函数重写
必须发生于父类与子类之间
而且父类与子类中得函数必须有全然同样的原型
使用virtual使命之后可以产生多态,假设不适用virtual。那就重定义
多态是执行期间依据详细对象的类型决定函数调用
版权声明:本文博主原创文章。博客,未经同意不得转载。