附录(一) 扩展知识:
1--> 面向对象的三个基本特征
1.0 封装:将客观事物抽象成类,每个类对自身的数据和方法实行protection(private,protected,public)
1.1 继承:广义的继承有三种实现形式:实现继承(指使用基类的属性和方法而无需额外编码的能力)、可视继承(子窗体使用父窗体的外观和实现代码)、接口继承(仅使用属性和方法,实现滞后到子类实现)。前两种(类继承)和后一种(对象组合=>接口继承以及纯虚函数)构成了功能复用的两种方式。
1.3 多态:是将父对象设置成为和一个或更多的与他的子对象相等的技术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作。简单的说,就是一句话:允许将子类类型的指针赋值给父类类型的指针。
2--> 多态的作用?
主要是两个:
2.0 隐藏实现细节,使得代码能够模块化;扩展代码模块,实现代码重用;
2.1 接口重用:为了类在继承和派生的时候,保证使用家族中任一类的实例的某一属性时的正确调用。
3-->是不是一个父类写了一个virtual 函数,如果子类覆盖它的函数不加virtual ,也能实现多态?
3.0 virtual修饰符会被隐形继承的。virtual可加可不加。子类的空间里有父类的所有变量(static除外)。
3.1 同一个函数只存在一个实体(inline除外)。子类覆盖它的函数不加virtual ,也能实现多态。
3.2 在子类的空间里,有父类的私有变量。私有变量不能直接访问。
4-->析构函数和虚函数的用法和作用?
4.0 析构函数是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载,只有在类对象的生命期结束的时候,由系统自动调用。 有释放内存空间的作用。
4.1 虚函数是C++多态的一种表现, 使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。
5-->基类的析构函数不是虚函数,会带来什么问题?
5.0 派生类的析构函数用不上,会造成资源的泄漏。
6-->多态类中的虚函数表是Compile-Time,还是Run-Time时建立的?
6.0 虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.
6.1 而对象的隐藏成员--虚拟函数表指针是在运行期--也就是构造函数被调用时进行初始化的,这是实现多态的关键。
7-->在C++中有没有纯虚构造函数?
7.0 构造函数不能是虚的。只能有虚的析构函数。
8-->巩固练习
8.0 如果ClassA中定义并实现虚函数int func(void),ClassB中也实现该函数,那么上述变量a->func()将调用哪个类里面的函数?如果int func(void)不是虚函数,情况又如何?为什么?
回答: 【参考答案】第一问调用的是B的。第二问调用A的。虚函数的一个典型应用,虚函数只能借助于指针或者引用来达到多态的效果。
8.1 看以下代码,回答: 【标准答案】A
class A { virtual void func1(); void func2(); }; class B: class A { void func1() { cout < < "fun1 in class B" < < endl; } virtual void func2() { cout < < "fun2 in class B" < < endl; } };
A, A中的func1和B中的func2都是虚函数
B, A中的func1和B中的func2都不是虚函数.
C, A中的func2是虚函数.,B中的func1不是虚函数.
D, A中的func2不是虚函数,B中的func1是虚函数.
回答: 【标准答案】A
附录(二) 扩展加强:
1. 简述多态的原理,和vptr指针。
当类中声明虚函数时,编译器会在类中生成一个虚函数表.虚函数表是一个存储类成员函数指针的数据结构,virtual成员函数会被编译器放入虚函数表中,存在虚函数时,每个对象中都有一个指向虚函数表的指针vptr指针
2. 如何证明virtual 虚函数中 vptr指针的存在。
定义虚函数,用sizeof求类的大小
3. 可不可以用父类指针进行++操作来遍历子类对象数组?
父亲指针和子类指针的步长一样就可以
4. 简述什么是纯虚函数,意义何在?
纯虚函数是一个在基类中说明的虚函数,在基类中没有定义,要求任何派生类都定义自己的版本
5. 什么是抽象类? 抽象类是否能够实例化。
一个具有纯虚函数的基类称为抽象类
不可以实例化
6. 何为面向抽象层编程?意义何在?
7. 将电脑组装案例 拆分成多文件形式。
8. 编写一个C++程序, 计算程序员( programmer )工资
1 要求能计算出初级程序员( junior_programmer ) 中级程序员 (
mid_programmer )高级程序员( adv_programmer)的工资
2 要求利用抽象类统一界面,方便程序的扩展, 比如:新增, 计算 架构师
(architect ) 的工资
9. 设计一个基类Shape包含成员函数Show(), 将Show()声明为纯虚函数。
Shape类公有派生矩形类Square(正方形)和圆类Circle(圆形),
问题1: 分别定义Show()实现其主要集合元素的显示。使用抽象类Shape
类型的指针,当它指向某个派生类的对象时,就可以通过访问该对象的虚函数
成员Show()。
问题2:用ShowArea()分别显示各种图形的面积.最后还要显示所有图形
的各个面积。要求积累指针数组,数组的每个元素指向一个派生类对象。