第22章 多重继承和类型变换
基于Directx的三维图形立体变换的实现

西南科技大学毕业设计(论文)题目名称:基于Directx的三维图形立体变换的实现年级:2003级■本科□专科学生学号:20035247学生姓名:宋彦宾指导教师:蒋体钢学生单位:信息工程学院技术职称:副研究员学生专业:通信专业教师单位:信息工程学院西南科技大学教务处制基于Directx的三维图形立体变换的实现摘要:目前在世界上三维图形大量的被应用到日常生活中,它是许多媒体应用程序和游戏的主体部分,所以掌握最新的三维技术是很有必要的。
本文首先研究了利用C#和Directx9编程以及立体几何技术,数学变换和几何图形技术来制作三维立体图形的方法,掌握了利用API接口创建窗口实现消息传递以及对坐标系,缓存,矩阵坐标变换的知识。
其次,利用3DS Max创建三维立体图形,加载到所编写的三位图形立体变换程序中,并进行调试。
设计主要完成了对绘制出来的电视机的平移,旋转和缩放技术的处理,最后通过程序对图形进行渲染使其更具有可观性。
关键词:API;Visual C#.Net;Direct3D;3DS MaxThe Realization of Three-Dimensional Graph Three-Dimensional Transformation Based on DirectxAbstract:In the world of nowadays, the three -dimensional graphics are applying to daily life in a large number. It is the main part of the game and applications of many media. So, it's necessary to master the latest 3-D technology.Firstly, this thesis researches on using C # and the Directx9 programming as well as the three-dimensional geometric technology, the mathematical manipulation and the geometric figure technology to manufacture the three-dimensional graphics. Mastering the use of the API interfaces to create a window that can realize message transmission. Acquainting the knowledge on the coordinate system, the texture and the matrix coordinate transformation. Secondly, the 3D models of the system were created by 3dsmax, then prepared to load the stereo 3D graphics transformation process, and debugging. The translation, the rotation and scaling of TV which have mapped out were completed in this design. Finally, by embroidering in procedure, the graphics were more arresting.Key words:API, Visual C#.Net, Direct3D, 3DS Max目录第1章绪论 (1)1.1 三维技术的现状 (1)1.2 编程语言简介 (2)1.3 三维图形立体变换的设计分析 (2)1.3.1 设计需求分析 (2)1.3.2 设计性能要求 (2)第2章DirectX9.0技术 (3)2.1 DirectX9.0的概念 (3)2.1.1 Direct3D的构架 (3)2.1.2 设计规划 (4)2.2 DirectX 9.0函数简介 (5)2.2.1 窗口类的处理 (6)2.2.2 创建IDirect3D接口 (7)2.2.3 创建IDirect3DDevice界面 (8)2.2.4 开始渲染 (9)2.2.5 顶点属性与顶点格式 (10)2.2.6 顶点缓冲 (10)2.2.7 索引缓冲 (12)2.2.8 D3D中的图元简介 (13)2.2.9 向量 (14)2.2.10 矩阵的操作 (15)第3章主体程序的设计与实现 (19)3.1 三维图形立体变换的设计 (19)3.2 三维图形立体变换设计具体实现 (19)3.2.1 利用.X文件图像获取 (19)3.2.2 利用画点画线函数生成图像 (23)3.2.3 图像的缩放 (33)3.2.4 图像的旋转 (34)3.2.5 图像保存为.TXT文挡 (37)3.2.6 渲染功能实现 (38)3.2.7 光源和观察矩阵的实现 (39)3.2.8 键盘的控制 (39)3.3 程序运行的调试 (40)总结 (41)4.1 设计开发小结 (41)4.2 项目改进方向和未来展望 (41)致谢 (42)参考文献 (43)附录 (44)第1章绪论1.1 三维技术的现状在计算机屏幕上绘图的最基本单位是点,点构成线,线又构成多边形,还可以朝空间发展,构成立体图行,如正方体、立方体、锥体、球等。
数据的整编和分析

常用统计分析方法——SPSS应用General Method of Statistical AnalysisSPSS Application杜志渊编著前言《统计学》是一门计算科学,是自然科学在社会经济各领域中的应用学科,是许多学科的高校在校本科生的必修课程。
在统计学原理的学习和统计方法的实际应用中,经常需要进行大量的计算。
因此,统计分析软件问世使强大的计算机功能得到充分发挥,不仅能够减轻计算工作量,计算结果非常准确,而且还节省了统计分析时间。
因此,应用统计分析软件进行数据处理已经成为社会学家和科学工作者必不可少的工作内容。
为了使高校的学生能够更好的适应社会的发展和需求,学习和使用统计软件已经成为当前管理学、社会学、自然科学、生物医学、工程学、农业科学、运筹学等学科的本科生或研究生所面临的普遍问题。
为了使大学生和专业人员在掌握统计学原理的基础上能够正确地运用计算机做各种统计分析,掌握统计分析软件的操作是非常有必要的。
现将常用的SPSS统计分析软件处理数据和分析数据的基本方法编辑成册,供高校学生及对统计分析软件有兴趣的人员学习和参考,希望能够对学习者有所帮助。
本书以统计学原理为理论基础,以高等学校本科生学习的常用的统计方法为主要内容,重点介绍这些统计分析方法的SPSS 软件的应用。
为了便于理解,每一种方法结合一个例题解释SPSS软件的操作步骤和方法,并且对统计分析的输出结果进行相应的解释和分析。
同时也结合工业、农业、商业、医疗卫生、文化教育等实际问题,力求使学生对统计分析方法的应用有更深刻的认识和理解,以提高学生学习的兴趣和主动性。
另外,为了方便学习者的查询,将常用统计量的数学表达式作为附录1,SPSS 中所用的主要函数释义作为附录2,希望对学习者能够的所帮助。
编者目录第一章数据文件的建立及基本统计描述 (1)§1.1 SPSS的启动及数据库的建立 (1)§1.1.2 SPSS简介 (1)§1.1.2 启动SPSS软件包 (3)§1.1.3 数据文件的建立 (5)§1.2 数据的编辑与整理 (8)§1.2.1 数据窗口菜单栏功能操作 (8)§1.2.2 Date数据功能 (9)§1.2.3 Transform 变换及转换功能 (10)§1.2.4 数据的编辑 (12)§1.2.5 SPSS对变量的编辑 (20)§1.3 基本统计描述 (26)§1.3.1 描述统计分析过程 (26)§1.3.2 频数分析 (28)§1.4 交叉列联表分析 (44)§1.4.1 交叉列联表的形成 (44)§1.4.2 两变量关联性检验(Chi-square Test卡方检验) (47)第二章均值比较检验与方差分析 (54)§2.1 单个总体的t 检验(One-Sample T Test)分析 (55)§2.2 两个总体的t 检验 (58)§2.2.1 两个独立样本的t检验(Independent-sample T Test) (58)§2.2.2 两个有联系总体间的均值比较(Paired-Sample T Test) (61)§2.3 单因素方差分析 (64)§2.4 双因素方差(Univariate)分析过程 (69)第三章相关分析与回归模型的建立与分析 (80)§3.1 相关分析 (80)§3.1.1 简单相关分析 (81)§3.1.1.1 散点图 (81)§3.1.1.2 简单相关分析操作 (83)§3.1.2 偏相关分析 (85)§3.2 线性回归分析 (89)§3.3 曲线估计 (100)第四章时间序列分析 (111)§4.1 实验准备工作 (111)§4.1.1 根据时间数据定义时间序列 (111)§4.1.2 绘制时间序列线图和自相关图 (112)§4.2 季节变动分析 (118)§4.2.1 季节分析方法 (118)§4.2.2 进行季节调整 (121)第五章非参数检验 (125)§5.1 Chi-Square Test 卡方检验 (127)§5.2 一个样本的K-S检验 (131)§5.3 两个独立样本的检验(Test for Two Independent Sample) (135)§5.4 两个有联系样本检验(Test for Two related samples) (138)§5.6 多个样本的非参数检验(K Samples Test) (141)§5.6 游程检验(Runs Test) (148)附录1 部分常用统计量公式 (154)§6.1 数据的基本统计特征描述 (154)§6.2 总体均值检验统计量 (156)§6.3 方差分析中的统计量 (158)§6.4 回归分析模型 (161)§6.5 非参数检验 (168)附录2 SPSS函数 (175)第一章数据文件的建立及基本统计描述在社会各项经济活动和科学研究过程中,经常获得许多数据,而这些数据中包含着大量有用的信息。
c++考试复习题

、选择题列对派生类的描述中,()是错误的。
A.一个派生类可以作为另一个派生类的基类B.派生类至少应有一个基类C.基类中成员访问权限继承到派生类中都保持不变D.派生类的成员除了自定义的成员外,还包含了它的基类成员.C++类体系中,能被派生类继承的有()。
A. 构造函数 B. 虚函数 C. 友元函数D.析构函数. 下列有关运算符重载的描述中,()是正确的。
A.运算符重载可改变其优先级B. 运算符重载不改变其语法结构C.运算符重载可改变其结合性D. 运算符重载可改变其操作数的个数、连接器所生成的文件的扩展名为()A、.cpp B 、.objC、.lib D 、.exe、下列符号中,()不是分隔符。
A 、;B 、类的构造函数和析构函数描述正确的是()。
A.构造函数可以重载,析构函数不能重载B.构造函数不能重载,析构函数可以重载C.构造函数可以重载,析构函数也可以重载D.构造函数不能重载,析构函数也不能重载. 下面对于友元函数描述正确的是()。
A.友元函数的实现必须在类的内部定义B. 友元函数是类的成员C. 友元函数破坏了类的封装性和隐藏性D. 友元函数不能访问类的私有成员. 派生类的对象对它的基类成员中()是可以访问的。
A.公有继承的公有成员B.公有继承的私有成员C.公有继承的保护成员D. 私有继承的公有成员.C++ 类体系中,不能被派生类继承的有()。
A.构造函数 B. 虚函数 C. 静态成员函数D.赋值操作函数. 以下()成员函数表示纯虚函数。
int vf(int); vf(int)=0;void vf()=0; void vf(int) { };. 下面对静态数据成员的描述中,正确的是()。
A.静态数据成员可以在类体内进行初始化B.静态数据成员不可以在类体内进行初始化C.静态数据成员不能受private 控制符的作用D.静态数据成员不可以用类对象调用. 继承具有(),即当基类本身也是某一个类派生类时,底层的派生类也会自动继承间接基类的成员。
4继承和多重继承

class BlackPerson:public Person { 人(Person) public: BlackPerson() { SetColor(black); } //... };
黑人类具有人类
的所有的属性和 方法,又有自己 的特殊之处(肤 色为黑色)。
人类: 父类(基类) 黑人类: 子类(派生 类) 黑人类与人类之 间是继承与被继 承的关系
参见下表:
• 存取方式与继承的关系:
public
存储类型 继承类型 public protected private
protected protected protected private
private 不可用 不可用 不可用
public protected private
举例
例如:
class Base {public: int m1; protected: int m2; private: int m3; }; class PrivateClass:private Base {public: void test() {m1=1;m2=2;m3=3;} };
}
判断上述程序的语句是否正确?
• 为什么?
四、派生类的构造函数和析构函数
• • • • 1 、单继承方式下派生类构造函数的定义 2、 多继承方式下派生类构造函数的定义 3 、派生类构造函数执行的次序 4、举例
1 、单继承方式下派生类构造函数的定义
• 定义格式如下: 派生类名::派生类构造函数名(参数表): 基类构造函数名(参数表) { //派生类构造函数的函数体 } 在这个定义格式中,派生类构造函数名后面内 的参数表中包括参数的类型和参数名,而基类 构造函数名后面括号内的参数表中只有参数名 而没有参数类型,并且这些参数必须是来源于 派生类的构造函数名后面括号内的参数。
《C 程序设计教程》课后习题答案

第1章C++及其开发环境概述一、问答题1.结构化程序设计主要有哪些劣势?【答案】(1)程序的开发效率低下(2)程序的可重用性差(3)程序的维护成本高(4)无法适应信息的快速膨胀和多样化2.面向对象的程序设计有哪些优点?【答案】(1)程序的开发效率高(2)程序代码的可重用性高(3)程序易于维护3.C++的发展经历了哪些阶段?【答案】C++语言起源于C语言。
1980年初期,美国贝尔实验室的Bjarne Stroustrup博士及其同事在C语言的基础上,从Simula67中引入面向对象的特征,开发出一种过程性与对象性相结合的程序设计语言,最初称为“带类的C”,1983年正式取名为C++。
后来,Stroustrup和他的同事陆续将运算符重载、继承、虚函数等特性引入C++,1989年后推出AT&T C++ 2.0版,并经过多次改进和完善,发展成为现在的C++。
4.C++主要有哪些特点?【答案】(1)C++可以被看成C语言的一个超集,是对C的增强和扩展。
因此,许多C代码可以不经修改即可为C++所用。
自然,也可以利用C++开发环境来开发C程序。
(2)C++几乎支持所有面向对象的程序设计特征,因此,利用C++不仅可以进行传统的结构化程序设计,而且可以较好地进行面向对象的程序开发。
(3)C++很好地保持了C的简洁、高效、灵活和接近汇编语言的特点,因此,C++程序的执行效率也很高。
5.一个C++程序一般由哪几部分构成?【答案】①预处理命令。
C++提供了三种预处理命令,即宏定义命令、文件包含命令和条件编译命令。
②全局声明部分。
此部分内容通常会给出用户自定义的数据类型声明,以及程序中所涉及变量的定义,例如类的声明。
数据结构③函数。
一个程序中可包含一个或多个函数,它们是执行用户指定操作的主要部分。
6.使用Visual C++ 开发C++程序时一般要经过哪几个步骤?每个步骤的作用是什么?相应地产生哪些文件?【答案】(1)编写程序C++是一种高级语言,所以用其编写的程序称为“源程序”,以.cpp做为后缀。
c++多重继承试题

(一)选择填空:(1) 下列对派生类的描述中,( )是错误的。
A. 一个派生类可以用作另一个派生类的基类。
B. 派生类至少应有一个基类。
C. 基类中成员被派生类继承后其映射的访问权限并无变化。
D. 派生类对象的栈区内存存储内容中除了本类部分的所有非静态数据成员外,还首先包含了它的基类部分的所有非静态数据成员。
(2) 主函数main可以访问派生类的对象中哪一类映射的基类成员?( )A. 公有继承的基类部分的公有成员。
B. 公有继承的基类部分的保护成员。
C. 公有继承的基类部分的私有成员。
D. 保护继承的基类部分的公有成员。
(3) 多继承派生类建立对象时,( )被最先调用。
A. 派生类自己的构造函数。
B. 祖先虚基类的构造函数。
C. 祖先非虚的基类的构造函数。
D. 派生类中子对象的构造函数。
(4)下列关键字中,( )不是类定义中使用的关键字:A.classB.publicC.switchD.private(二)判断下列描述的正确性,对者划√,错者划,错者划者划(1) C++语言中,允许单继承,也允许多继承。
(2) 派生类不能再派生出新的派生类。
(3) 在公有继承中,派生类对象的成员函数可以访问基类部分中的私有成员。
(4) 在公有继承中,派生类对象的成员函数不可以访问基类部分中的保护成员。
(5) 在私有继承中,派生类对象的成员函数不可以访问基类部分中的公有成员。
(6) 在保护继承中,派生类对象的成员函数可以访问基类部分中的保护成员。
(7) 用class定义的类中,缺省的访问权限是公有的。
s定义的类中,缺省的访问权限是公有的。
(1)义的类中,缺省的访问权限是公有的。
(三)写出以下程序运行结果// exer_ch4_3.cpp#include<iostream.h>class A{int a,b;public:A(int i, int j){a=i; b=j;}void Move(int x, int y){a+=x; b+=y;}void Show( ){cout<<"("<<a<<", "<<b<<")"<<endl;}};class B : public A{int x, y;public:B(int i, int j, int k, int l) : A(i, j){x=k; y=l;}};void main( ){A a(1, 2);B b(3, 4, 5, 6);b.Move(7, 8);b.Show( );}(四)该表找出程序中错误语句,修改后显示运行结果。
《面向对象程序设计》习题四答案

面向对象程序设计习题4
(3) 下列程序中,基类base和派生类d1、d2中都含有私有、 保护和公有成员,d1类是base的派生类,d2是d1问属性的变化
面向对象程序设计习题4 #include <iostream.h> #include <iostream.h> class base class base {{private: int n1; private: int n1; protected: int k1; protected: int k1; public: public: base(){n1=0;k1=1;} base(){n1=0;k1=1;} void fun1(){cout<<n1<<k1<<endl;} }; void fun1(){cout<<n1<<k1<<endl;} }; class d1:public base class d1:public base {{ int n2; int n2; protected: protected: int k2; int k2; public: public: d1(){n2=10;k2=11;} d1(){n2=10;k2=11;} void fun2(){cout<<n1<<k1<<endl; cout<<n2<<k2<<endl;} }; void fun2(){cout<<n1<<k1<<endl; cout<<n2<<k2<<endl;} }; class d2:public d1 class d2:public d1 {{ int n3; int n3; protected: protected: int k3; int k3; public: public: d2(){n3=20;k3=21;} d2(){n3=20;k3=21;} void fun3() void fun3()
继承与派生类答案

继承与派生类知识要点1.掌握继承和派生的定义,派生类的定义方法。
(1)掌握继承的两种类型:单继承和多继承。
(2)掌握private,public,protected三种继承方式的特点。
继承方式决定了基类中的成员在派生类中的属性。
三种继承方式的共同点:基类的private成员在派生类中不可见。
区别:对于私有继承,基类的public、protected成员在派生类中作为private成员;对于公有继承,基类的public、protected成员在派生类中访问属性不变;对于保护继承,基类的public、protected成员在派生类中作为protected成员。
(3)掌握派生类中的构造函数和析构函数的使用。
基类的构造函数和析构函数不能继承,所以必要时在派生类中定义自己的构造函数和析构函数。
派生列的构造函数完成基类中新增数据成员和基类数据成员的初始化,基类数据成员的初始化通过基类构造函数来实现。
(4)掌握派生类的同名覆盖规则。
(5)掌握赋值兼容规则。
基类对象可以使用公有派生类对象来代替,包括:派生类对象可以赋值给基类对象;派生类对象可以初始化基类对象的引用;基类类型指针可以指向派生类对象。
2.掌握多重继承的概念、定义方法、多重继承派生类构造函数的执行顺序。
派生类构造函数的执行顺序是先执行所有基类的构造函数(顺序按照定义派生类时指定的各基类顺序),在执行对象成员所在类的构造函数(顺序按照他们在类中的声明顺序),最后执行派生类构造函数体中的内容。
3.掌握虚基类的概念和定义方法。
在多重继承中,如果多条继承路径上有一个公共的基类,则在这些路径的汇合点上的派生类会产生来自不同路径的公共基类的多个拷贝,如果用virtual把公共基类定义成虚基类,则只会保留公共基类的一个拷贝。
典型例题分析与解答例题1:下列对派生类的描述中,()是错误的。
A.一个派生类可以作为另一个派生类的基类B.派生类至少有一个基类C.派生类的成员除了它自己的成员外,还包含了它的基类成员D.派生类中继承的基类成员的访问权限到派生类保持不变答案:D分析:一个派生类可以作为另一个派生类的基类。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
12
C/C++程序设计 程序设计
[例] 关键字 例 关键字virtual对多重继承的影响.从输出结果注意构造 对多重继承的影响. 对多重继承的影响 函数调用的次序. 函数调用的次序. # include<stdio.h> class CTop { public: int mt; CTop (int n=0) { mt=n; printf ("%d.CTop()this=%p,%p\n",mt,this,&mt); } };
CTop
CBase1
CBase2
long l;0065FDE8 int b2;0065FDEC int d; 0065FD F0
CBase1
CBase2
ClassD
int mt;0065FDF4
ClassD
无关键字virtual的内存布局 的内存布局 无关键字
virtual继承的内存布局序设计 程序设计
class ClassD: public CBase1,public CBase2 { public: int d; ClassD (int n=3) { d=n; printf ("ClassD()this=%p,%p\n",this,&d); } int Show(); }; int ClassD::Show() { CBase1::Show(); CBase2::Show(); printf ("%d.ClassD::Show()sizeof(ClassD)=%d\n", d,sizeof (ClassD)); return 0; } void main() { ClassD d; d.Show(); }
13
C/C++程序设计 程序设计
struct CBase1:virtual public CTop { CBase1 (int n=1) { b1=n; printf ("CBase1()this=%p,%p\n",this,&b1); } void Show() { printf("%d.CBase1::Show()sizeof(CBase1)=%d\n", b1,sizeof(CBase1)); } int b1; };
6
C/C++程序设计 程序设计
class CDerived:public CBase2, virtual public CBase1 { public:CDerived (int n=3) { m_d=n;printf ("CDerive::CDeriv this=%p,%p\n",this,&m_d); } int m_d; int Show(); }; int CDerived::Show() { CBase1::Show(); CBase2::Show(); printf ("%d.CDerived::Show() sizeof (CDerived) =%d\n",m_d, sizeof (CDerived)); return 0; } void main() { CDerived d; d.Show(); }
3
C/C++程序设计 程序设计
多继承的派生格式为: 多继承的派生格式为: class 派生类名: 派生类名: 继承方式1 基类名1, 继承方式2 基类名2,..., 继承方式 基类名 继承方式 基类名 virtual public 基类名 基类名n { 派生类的成员声明语句 }; 派生类的成员声明语句; ; 直接基类是唯一的即冒号之后的基类名CBasen等不能 直接基类是唯一的即冒号之后的基类名CBasen等不能 重复出现, 重复出现,基类构造函数的调用次序根据冒号之后基类表的 排列顺序进行,虚拟继承优先. 排列顺序进行,虚拟继承优先.析构函数的调用一般遵循与 对应构造函数相反的次序进行. 对应构造函数相反的次序进行.基类的说明次序影响派生类 对象的内存分布, 对象的内存分布,但语言未规定各基类成员在内存的先后顺 这取决于编译器的具体实现. 序,这取决于编译器的具体实现.
1
C/C++程序设计 程序设计
一,多个直接基类 二,虚拟基类 三,多继承的构造函数 四,名称的二义性
2
C/C++程序设计 程序设计
一,多个直接基类
基类是简单的类,派生类是略微复杂的类. 基类是简单的类,派生类是略微复杂的类.一个派生类 同时继承若干直接基类, 同时继承若干直接基类,意味着派生类的功能是基类功能的 综合. 综合. 多继承的语法格式是通过若干继承方式和直接基类名引 入的,继承方式由关键字private,public,protected给出, 给出, 入的,继承方式由关键字 给出 该继承方式的含义等同于单继承情形.关键字virtual出现于 该继承方式的含义等同于单继承情形.关键字 出现于 多继承的语法格式且贡献额外的4字节内存到派生类的对 多继承的语法格式且贡献额外的 字节内存到派生类的对 但与多态类的动态绑定无关, 象,但与多态类的动态绑定无关,仅是为了解决内存共享名 称歧义而卷入进来的. 称歧义而卷入进来的.
14
C/C++程序设计 程序设计
class CBase2: public virtual CTop { public: CBase2 (int n=2) { b2=n;printf("CBase2()this=%p,%p\n",this,&b2); } void Show() { printf("%d.CBase2::Show()sizeof(CBase2)=%d\n", b2,sizeof(CBase2)); } long l; protected: int b2; };
4
C/C++程序设计 程序设计
下面是一个简单的示例程序. 下面是一个简单的示例程序. [例] 多个直接基类 例 # include<stdio.h> struct CBase1 { CBase1(int n=1) { m_b1=n; printf ("CBase1::CBase1()this=%p,%p\n",this, &m_b1);} void Show() { printf ("%d.CBase1::Show() sizeof(CBase1)=%d\n", m_b1,sizeof (CBase1)); } int m_b1; };
8
C/C++程序设计 程序设计
程序有virtual的运行输出结果如下 的运行输出结果如下: 程序有 的运行输出结果如下 CBase1::CBase1()this=0065FDF4,0065FDF4 CBase2::CBase2()this=0065FDE4,0065FDE8 CDerive::CDerive this=0065FDE4,0065FDF0 1.CBase1::Show() sizeof(CBase1)=4 2.CBase2::Show() sizeof(CBase2)=8 3.CDerived::Show() sizeof(CDerived)=20
long l; 0065FDE4
long l;
0065FDE8
CBase1
CBase2
int m_b2; 0065FDEC int m_b1; 0065FDF0 int m_d; 0065FDF4 CDerived
int m_b2; 0065FDE8 vbp 0065FDEC
int m_d; 0065FDF0 int m_b1; 0065FDF4
C/C++程序设计 程序设计
多继承(multiple inheritance)指在一个继承树层次的剖 多继承 指在一个继承树层次的剖 面上派生类可以拥有不止一个直接基类.多重继承是C++语 面上派生类可以拥有不止一个直接基类.多重继承是 语 言后期引进的代码重用的模式, 言后期引进的代码重用的模式,单一继承对应派生类上逆时 恒只有一个直接基类. 恒只有一个直接基类.多重继承打破了单一继承这种单枝独 上的简单性. 上的简单性. C风格的类型转换对于系统级的操作是必不可少的. 风格的类型转换对于系统级的操作是必不可少的. 风格的类型转换对于系统级的操作是必不可少的 C++鉴于 风格的类型转换未提供足够明显的安全保障 鉴于C风格的类型转换未提供足够明显的安全保障 鉴于 机制,特引进新形式的类型变换规则. 机制,特引进新形式的类型变换规则.
11
C/C++程序设计 程序设计
二,虚拟基类
关键字virtual可以在多继承的时候修饰直接基类中的一 可以在多继承的时候修饰直接基类中的一 关键字 个或多个, 限定的基类称为虚拟基类, 个或多个,被virtual限定的基类称为虚拟基类,对应的继承 限定的基类称为虚拟基类 模式可称为虚拟继承.虚拟继承不同于虚拟函数, 模式可称为虚拟继承.虚拟继承不同于虚拟函数,虽然两者 同用一个关键字virtual. 相应于虚拟继承编译器增添 字节 同用一个关键字 . 相应于虚拟继承编译器增添4字节 的数据以鉴别非虚拟继承. 的数据以鉴别非虚拟继承.这四个字节的数据项可称为指向 虚基类表(virtual base class table)的指示符 的指示符vbp. 虚基类表 的指示符 . 虚拟基类的数据成员只有一个内存映像为派生类所共享 并且可适当减少基类的歧义. 并且可适当减少基类的歧义.
5
C/C++程序设计 程序设计
class CBase2 { public: CBase2 (int n=2) { m_b2=n; printf ("CBase2::CBase2()this=%p,%p\n",this,&m_b2); } void Show() { printf ("%d.CBase2::Show() sizeof (CBase2) =%d\n",m_b2,sizeof (CBase2)); } long l; protected: int m_b2; };