VisualC++.Net程序设计实践教程ppt.ppt

上传人:za****8 文档编号:16083893 上传时间:2020-09-18 格式:PPT 页数:125 大小:1.56MB
返回 下载 相关 举报
VisualC++.Net程序设计实践教程ppt.ppt_第1页
第1页 / 共125页
VisualC++.Net程序设计实践教程ppt.ppt_第2页
第2页 / 共125页
VisualC++.Net程序设计实践教程ppt.ppt_第3页
第3页 / 共125页
点击查看更多>>
资源描述
1,Visual C+.Net程序设计实践教程,2,第2章 程序结构,程序可以看成是由数据结构和算法组成的。数据结构体现在对数据的描述,而算法反映了对数据的操作及处理。任何一门计算机语言都必须包括数据类型、运算符与表达式,及基本控制语句等内容来定义和实现程序中的数据结构和算法。 Visual C+.NET在C/C+基础上引入“托管(Managed)”概念之后,使之成为“C+托管扩展语言”(简单称“托管C+”或“MC+”)。它除了保留标准C+的全部功能,还扩展了很多其他功能。例如,数据类型除包括原来C+的数据类型外,又增加了多种“托管基本数据类型”。不过,如常量、变量、运算符和控制语句等这些C+基本知识还没有太大变化。本章我们主要介绍托管C+的基础内容,其中包括数据类型、常量和变量、运算符和表达式、以及各种控制语句。,3,本章学习目标:,掌握托管C+的数据类型 理解常量和变量的概念 掌握各种不同数据类型常量的表示方法及其应用 掌握变量的定义和初始化,及其应用 区分各种不同的运算符及其用法,并掌握它们的优先级高低。 掌握各种控制语句的格式、用法及区别。,4,2.1 数据类型,在程序设计中,数据是程序的必要组成部分,也是程序处理的对象。不同的数据有不同的数据类型,不同的数据类型有不同的数据结构和存储方式,并且参与的运算也不同。 托管C+的数据类型分为3类:基本类型、派生类型以及复合类型。 基本数据类型是托管C+系统的内部数据类型。它主要包括以下3部分。首先是标准C/C+内部的基本数据类型,它分为4类。,5,2.2 标识符和关键字,标识符和关键字都是托管C+程序中基本要素。在实际应用时,它们能在一定程度上反映它所表示的变量、常量、对象或类的意义及用法,这样就增加了程序的可读性。,6,2.2.1 标识符,标识符是用来代表常量、变量、函数、对象或类等实体的代号。标识符的建立是通过在各实体的定义中对其进行说明实现的。标识符说明以后就可以在后面的程序语句中使用它来代表相关实体,并可进行相关的运算操作。,7,2.2.2 关键字,关键字,又叫保留字。它是托管C+编译程序中预定义的具有特殊意义的标识符。各关键字都有其特定的含义和用法,和用户自定义的标识符不同,不能当作一般的标识符使用。,8,2.3 常量和变量,在程序设计过程中,有时需要用到的数据是固定不变的,有时只是用来暂存某个数据单元。因此,根据程序中的数据的可变性,数据可分为常量和变量两大类。在程序的执行过程中保持数值不变,且程序本身不能改变其值的数据,称为常量。在程序运行中数值经常变化,称为变量。,2.4 运算符与表达式,运算符按参与运算的操作数的个数可分为:单目运算符(如+、-)、双目运算符(如+、-、*、/、%)、三目运算符(如 ?)。按其功能不同分为7类:算术运算符、赋值运算符、关系运算符、逻辑运算符、位运算符、条件运算符、逗号运算符和sizeof运算符,2.5 程序控制语句,程序中各语句是按一定的顺序逐个执行。实现控制程序执行的语句称为程序控制语句。托管C+中程序控制语句主要有三种:选择语句、循环语句和跳转语句。,11,第4章 数组和字符串,在第2章中,已经介绍了在编写托管C+代码时可用的基本数据类型,除了基本数据类型外,也可以使用基本数据类型构造新的数据类型,例如,数组类型、结构类型、联合类型、枚举类型等,本章首先介绍数组,其他几种在后续章节中介绍。在进行托管代码编程时,既可以使用非托管数组(包括标准C+数组)也可以使用托管数组,本章重点介绍托管数组. 除了数组之外,字符串也是最常用的数据类型之一。在托管C+中又定义了新的字符串类型,即托管字符串,用String类和StringBuilder类表示,托管字符串比标准C+中的字符串功能更强大、使用起来更方便;使用它们也可构造字符串数组;除此之外,在进行托管代码编程时仍可使用标准C+中的字符串和字符串数组。,12,本章学习目标:,了解托管C+数组和标准C+数组的区别 学会定义和使用一维数组和二维数组 了解数组与函数的关系 了解定长数组和变长数组的区别 学会使用字符串 了解String类和StringBuilder类 学会使用字符串数组,13,4.1 数组概述,在编程过程中,将一部分具有特定功能的代码或者重复出现的代码编写成一个独立的代码单元,并给予特定的名称,供其他程序调用,这种类型的代码单元被称为函数。每个程序通常都包含一个主函数,例如main、_tmain、WinMain、_tWinMain等,它们是程序运行时的入口点,并由操作系统进行调用。 要使用函数,首先需要定义函数,函数的定义指定了函数所要完成的功能。函数的定义包含了两个部分:函数头和函数体。函数头是函数定义中的第一行,在左花括号之前;函数体位于花括号对中,它包含了调用函数时要执行的代码。 函数定义的一般形式为: 类型定义符 函数名(参数表) 函数体 ,14,4.1 数组概述,数组是数目固定、类型相同的若干个变量的有序集合,它代表一组连续的内存空间,常被用来存储一组彼此互相关联的数据。,15,4.2 托管数组与非托管数组,托管数组除了其占用的内存空间可由公共语言运行库自动管理之外,在定义、赋值、引用等方面与标准C+数组也有一些区别,本节将介绍在托管代码编程中怎样定义和使用托管数组。另外,在托管代码编程中也可使用非托管数组(包括标准C+数组),但当在托管类型(如托管类)中定义非托管数组时,所采用的格式与在标准C+中略有不同,本章后面会介绍;在托管类型之外使用标准C+数组时仍可像在非托管代码编程(即使用VC+环境但不使用.NET Framework类库的C+编程)中那样使用,16,4.3 数组和函数,为了能够更好地处理数组,需要把数组传递到函数,可以传递单个数组元素,也可以传递整个数组。在托管代码编程中,传递整个数组或传递数组元素与在标准C+编程中是类似的,本节只举例介绍怎样传递托管数组和托管数组元素,至于怎样传递标准C+数组和数组元素,方法也的一样的。另外,在托管代码编程中,数组也可作为函数的返回类型。,17,4.4 数组的应用,由于使用数组非常有利于处理一组相关的数据,所以,数组在编程中很常用。本节将介绍数组的两个重要应用:使用数组生成随机数序列和使用数组进行排序。,4.5 字符串,一般情况下,字符串是作为单元来看待的一系列字符。如果没有字符串,就不可能编写结构良好和符合工程学的程序。字符串可分为固定长度的字符串和可变长度的字符串两种。固定长度的字符串是作为字符数组实现的。在实现固定长度的字符串时,必须首先指定变量的尺寸;如果尺寸太小,就不能存储所有数据,如果尺寸太大,就会浪费存储空间。可变长度的字符串是通过创建在接纳数据时可以扩展和收缩的结构来实现的;这时,要存储只有一个字母组成的人名,该结构就只提供一个字符的存储空间,要存储一个由30个字符组成的人名,该结构就进行扩展,提供30个字符的存储空间。可变长度字符串的一种是长度可控字符串,它添加了一个说明字符串中字符数量的计数器,字符串操作函数将使用这个计数器确定数据的实际长度,这是C+字符串类中使用的技术。,4.6 字符串数组,字符串类型也可以用来构造数组。在前面的程序示例中,已经使用过字符串数组。在编程中使用字符串数组是很常见的。例如,数据库的输入处理程序可能会将用户命令与包含合法命令的字符串数组进行比较查证。,20,第5章 指针与引用,指针是C+语言中最强大的功能之一,同时它也是C+ 中比较麻烦的功能之一。它就像一把锋利的双刃剑,如果正确使用指针,它可以使用程序变得简洁、运行效率显著提高;同时,如果未能正确使用指针,它也很容易导致整个程序的崩溃。尽管如此,指针在C+程序中的用途很广。例如,指针可以用来处理字符串、数组,以及动态内存分配等。,21,本章学习目标:,理解指针的概念 如何在托管C+中使用托管指针变量 使用托管指针操作数组 托管指针在函数中的应用 在托管C+中使用引用 引用在函数中的使用,22,5.1 指针的概念,指针就是变量在内存中的地址。当要存取变量中的值时,有两种方法可实现:一种是直接访问,即利用变量名来直接访问变量中保存的数值;另一种是间接访问,即通过变量的内存地址访问变量中保存的数值。通常变量的地址被保存在另一个变量中,这个变量被称为指针变量。指针变量中保存了另一个变量在内存中的地址(即变量的指针)。,23,5.2 定义指针变量,如果在程序中想要使用一个指针变量,必须先定义一个指针变量。定义一个指针变量包括:定义基本数据类型、符号“*”和变量名。下面是一个定义指针变量的具体例子: int a,b; int *ptr1,*ptr2; 上面第一行定义了两个整型变量a和b,第二行定义了两个非托管的指针变量:ptr1和ptr2,它们是指向整型变量的指针变量。左端的int定义了指针变量可以指向的变量类型。如ptr1和ptr2可以指向任何整型变量,但它们不可以指向浮点型变量。 定义一个非托管指针变量的典型形式如下: 类型 * 变量名 定义托管指针的例子如下: Int32 *ptr1; int _gc *ptr2; 当定义一个指针变量后,指针变量保存了内存中一个不确定的地址。如果在程序中使用了这样的指针,可能会导致系统的错误。困此,还需要让指针变量指向变量。,24,5.3 指针运算符,有了变量和指针变量后,如何将它们联系起来?即让指针变量指向变量。这需要用到两个操作符:*和 在上面的代码中,使用运算符 int _gc *p; p= 在上述代码中,第一行定义了一个托管数组a,并在内存中为它分配了能保存10个整数的内存区域。第2、3行代码定义了一个指针变量,并将数组中第一个元素的地址保存到指针变量,即托管指针指向托管数组的首地址。需要注意的是:用指针操作托管数组时,需要将指针定义为托管指针。,26,5.5 指针和函数,指针一个最有用的应用之一是在函数中。托管C+提供了三种参数传递方法值传递、地址传递和引用传递。其中,地址传递就是在使用指针作为函数的形参。同时,函数也可以返加一个地址。,5.6 引用,托管C+提供了一个与指针密切相关的特殊数据类型引用。引用是一个变量的别名,定义引用类型变量,实质上是给一个已经定义的变量起一个别名。 为了建立一个引用类型变量,需要先标明目标变量的类型,后面跟引用运算符“ 在这里,要求intNum是已经定义过的变量,而引用类型变量Num仅仅是它的别名。在定义了一个变量的引用后,所有对这个引用Num的操作,实质上都是对被引用变量intNum的操作。需要注意,此处的符号“&”不表示取地址,它是定义引用变量的专用运算符。 定义一个引用类型变量后,系统并不会为它会配内存空间,引用类型变量与被引用的变量同用一个内存空间。,5.7 引用与函数,在前面曾经提到过,函数之间传递参数有三种方法值传递、地址传递和引用传递。其中引用传递和地址传递的效果相同,形参改变后实参也会随之改变。 当函数之间使用引用传递参数时,需要在被调用函数的形参前加引用运算符“&”。例如,下面的程序用来求二次方程的根。 在该程序中,主函数将变量以引用传递的方式传递给函数getData、displayRoot和quadratic函数。其中getData函数用于获取用户输入的参数,quadratic函数用于计算二次方程的根,displayRoot则用来显示二次方程的根。,29,第6章 类与对象,面向对象编程是以术语对象来模拟现实世界。世界上的每件事物都可以抽象为对象。VC+.NET是面向对象的语言,因为在VC+.NET中编程的重点是创建对象、操作对象及使对象协同工作。类是对象的抽象和概括,是封装的基本单位,它把数据和方法封装在一起。类和对象的关系是归纳和演绎,类是对象的归纳、对象是类的演绎。 VC+.NET是面向对象的,但也可以面向过程。而托管C+基于.NET框架重新设计的,新增和加强了许多新的特性。例如增加了结构化异常处理、托管代码和符合通用语言运行时(CLS)等特性。这样在编程过程中又有许多新的应用。,30,本章学习目标:,面向对象的程序设计 类的定义和创建 构造函数和析构函数的用法 对象数组的概念和用处 指针和引用在对象中的应用,31,6.1 对象,对象是结构的进化,是为了更好地解决问题而引入的。面向对象的程序设计是以需解决的问题中所涉及到的各种对象为主要矛盾。面向对象问题的求解就是力图从实际问题中抽象出这些封装了数据和操作的对象,通过定义属性和操作来表述他们的特征和功能,通过定义接口来描述他们的地位及与其它对象的关系,最终形成一个广泛联系的可理解、可扩充、可维护,更接近于问题本来面目的动态对象模型系统。,32,6.2 类的定义,类是对象的抽象和概括,是封装的基本单位。类是一种复杂的数据类型,它是将不同类型的数据和与这些数据相关的操作封装在一起的集合体。 类的结构(也即类的组成)是用来确定一类对象的行为的,而这些行为是通过类的内部数据结构和相关的操作来确定的。这些行为是通过一种操作接口来描述的(也即平时我们所看到的类的成员函数),使用者只关心的是接口的功(也就是我们只关心类的各个成员函数的功能),对它是如何实现的并不感兴趣。而操作接口又被称为这类对象向其他对象所提供的服务。,33,6.3 类的实现,构造函数和析构函数在C+类定义中必须有的成员函数。如果少了析构函数,就会造成内存的泄漏。而在.NET情况下有所改善,在.NET下由于有垃圾回收机制,这样析构函数在多数情况下可以不要。 构造函数的名称必须同类名相同,以便系统能识别为构造函数。当使用声明语句创建一个对象时隐含调用相应类的构造函数,为对象分配空间和初始化。析构函数的名称与类名相同且前面加有非运算符“”,表明其功能和构造函数相反。,34,6.4 对象数组,对象数组是指数组元素为对象的数组。该数组中若干个元素必须是同一个类的若干个对象。 对象数组的定义、赋值和引用与普通数组一样,只是数组的元素与普通数组不同,它是同类的若干个对象。,35,6.5 对象指针和引用,指针与引用有强大的功能,特别是在对类的使用过程中,能显著的减少内存的使用量。下面对指针和引用的用法做详细的介绍。,36,第7章 类的更多功能和其他类型,在第6章对类和对象进行了详细的讲解,因为类是托管C+中非常重要的自定义类型。本章将进行补充一些更深入的用法。 另外托管C+具有丰富的数据类型,它包括基本类型、派生类型和复合类型。在第2章中我们已经讲到托管C+的基本数据类型,并在前面章节还讲到了数组和指针等类型。数组中的各元素是属于同一类型的,但有时需要将不同类型的数据组合成一个有机整体,以便于引用,并且这些组合在一个整体中的数据是互相联系的。这就是本章要讲到的托管C+的复合类型中的3种:结构、联合和枚举。本章主要讲述静态成员、this指针、以及结构、联合和枚举三种复合类型的定义,其变量的声明及综合应用和运算符重载。,37,本章学习目标:,静态数据成员 静态函数成员 this指针 理解结构的含义,掌握结构的声明、结构变量的声明及其引用 理解结构数组的应用 掌握联合的声明、联合变量的声明及其成员的引用 掌握枚举的声明和枚举变量的声明 了解结构、联合和枚举的区别与联系 运算符重载,38,7.1 静态成员,静态成员的提出是为了解决数据共享的问题。实现共享有许多方法,如:设置全局性的变量或对象是一种方法。但是,全局变量或对象是有局限性的。这一节里,我们主要讲述类的静态成员来实现数据的共享。,39,7.2 this关键字,this指针是一个隐含于每一个成员函数中的特殊指针。它是一个指向正在被该成员函数操作的对象,也就是要操作该成员函数的对象。 当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含作用this指针。而通常不去显式地使用this指针来引用数据成员。同样也可以使用*this来标识调用该成员函数的对象。,40,7.3 结构,构造函数和析构函数在C+类定义中必须有的成员函数。如果少了析构函数,就会造成内存的泄漏。而在.NET情况下有所改善,在.NET下由于有垃圾回收机制,这样析构函数在多数情况下可以不要。 构造函数的名称必须同类名相同,以便系统能识别为构造函数。当使用声明语句创建一个对象时隐含调用相应类的构造函数,为对象分配空间和初始化。析构函数的名称与类名相同且前面加有非运算符“”,表明其功能和构造函数相反。,41,6.4 对象数组,有时我们需要将不同类型的数据组合成有机整体,以方便引用这些数据。这些数据之间存在着一定的联系。例如:一个人的基本信息:姓名、性别、年龄、身高、职业等;一个职工的工号、部门、职务、政治面貌等。如果将这些数据分别存放在不同的变量中,就不能体现它们之间的关系。因此我们可能经过使用结构将这些不同类型的数据定义为一个特殊的数据类型,这样就可以方便的使用这些数据了 结构是由基本数据类型构成的、并用一个标识符来命名的各种变量的组合。结构内可以使用不同的数据类型。,42,7.4 联合,有时需要使用几种不同类型的变量存到同一段内存单元中。例如,可把一个整型变量、一个字符型变量和一个实型变量放在同一个地址开始的内存单元中。这3个变量在内存中占的字节数不同,但都从同一地址开始存放。也就是使用覆盖技术,几个变量互相覆盖。这种几个不同类型的变量共占用一段内存的结构,称为“联合”。,7.5 枚举,枚举是值类型的一种特殊形式,它从System:Enum继承而来,并为基本类型的常数值提供一种方便记忆的方法。,7.6 运算符重载,尽管托管C+语言有丰富的数据类型和运算符,但仍然不能满足应用编程的一些需求。复数及其操作就是这样一个例子。虽然用户可以定义一个复数类,然后利用成员方法实现数据之间的运算操作,但却没有运算符操作来得更为的直接和简单。,45,第8章 动态主机配置协议,如果有哪个TCP/IP应用层协议和服务可以被称为“TCP/IP网络管理员之友”,那就是DHCP。这是因为DHCP缓解了手工管理IP地址的繁琐劳动,这些劳动要求管理员手工配置每个典型的客户机,并记录使用IP地址的计算机(在多宿主计算机上就是接口)。,46,本章学习目标:, 理解DHCP向客户机提供的基本服务 解释DHCP的背景、历史和起源 介绍支持DHCP执行功能的基本组成软件 理解使用DHCP进行IP地址管理的特点 阅读并理解基础性DHCP消息类型 解释并配置DHCP服务所需的基本设置,47,8.1 DHCP简介,DHCP是一种服务,它允许网络管理员配置服务器,为不需要固定IP地址的工作站、台式机和客户机分配和管理IP地址集。在缺少动态DNS(动态DNS可以在DNS层次结构中自动传播IP地址的变动,而不要求手动更新数据库)和重要的公共出现(例如可公开访问的Web、e-mail、FTP和其他服务器及服务)的情况下,大部分服务器要求很少有变动的IP地址,需要可以长期使用的IP地址。其他情况,比如对不太面向公众的主机桌面客户机,DHCP就可以提供较好的服务。,48,8.2 理解DHCP的IP地址管理,当DHCP客户机没有IP地址时(第一时间引导或租约失效后引导),它必须广播一个申领IP地址的请求,这个进程称为DHCP发现。可接收这个发现广播的DHCP服务器向客户机提供一个在特定时间段内有效的IP地址(租用时间)。根据其所用的服务器不同(Windows 2000为8天,Windows NT 4.0为36小时),DHCP租用时间不同。,49,8.3 标准地址发现进程,当一台DHCP客户机被引导时,可以在网络上通信之前执行标准地址发现进程。这个进程成功完成后,DHCP客户机使用一个复制的IP地址ARP广播测试这个IP地址。,50,8.4 地址续租过程,当DHCP客户机接收到来自DHCP服务器的地址时,客户机也接收到一个租用时间,并注意到接收到这个地址的时间,然后DHCP客户机可以在租用时间基础上计算续租时间(T1)和重绑定时间(T2)。,51,8.5 DHCP地址释放进程,尽管没有规范要求,客户机还是应该通过向服务器发送DHCP Release数据包来释放其地址(称为释放过程)。DHCP Release数据包通过UDP发送,并且DHCP不发送任何告知收悉信息。如果客户机不发送DHCP Release数据包,在租约到期时DHCP服务器就会自动释放地址。,8.6 DHCP数据包结构,本节将介绍DHCP数据包命令和定义域值及选项。 1操作代码域 2硬件类型域 3硬件长度域 4Hops域 5事务IP号码域 6从引导开始计秒域 7标记域 8客户机IP地址域 9你的IP地址域 10服务器IP地址域,8.7 DHCP中的广播和单播,当学习DHCP通信时,你会注意到它们使用广播和单播寻址的奇特混合。DHCP客户机必须使用广播,直到通过发现、提供、请求和告知收悉过程的成功完成获取IP地址为止。表8-3明确了DHCP服务器使用广播和单播的时间。,53,8.8 DHCP转接代理,DHCP引导进程严重依靠广播,但大部分路由器不转发广播。这就需要在每一个网络段上都有一个DHCP服务器,或定义的特殊功能使发现进程广播到远程DHCP服务器。这个转接代理功能解决了第二种配置设计。,54,8.9 Microsoft DHCP作用域和类,Microsoft用术语“作用域”来定义一组Windows 2000 DHCP服务器能用来分配给客户机的IP地址。因为这些DHCP服务器不能互相通信,所以这个DHCP服务器职责是保证在这些服务器之间没有作用域值重叠。,55,8.10 DHCP的前景,随着IPv6不断发展和部署,DHCP的角色发生了很大的改变。IPv6的一个极大的优势是自动配置,IPv6主机能用它们的硬件地址和Neighbor Discovery进程建立局部IP地址。,56,8.11 发现并修理DHCP故障,发现DHCP障碍并进行修理的最好方法是使用分析器,把标准的4个数据包引导顺序和有问题的引导顺序进行比较。要判定分配给Windows 2000设备什么地址需要运行IPCPNFIG实用工具。,57,第8章 继承与多态,在程序设计中,为了能利用已有的成果,减少编程的工作量,实现代码复用,类使用了继承的机制。利用继承机制,新的类可从已有的类中获得数据成员和成员函数,并且可根据需要增加新的成员。 由于继承,就需要在不同层次的类之间提供接口,多态就很好的解决了这一问题。多态性是指不同对象接收到相同消息时,根据对象类的不同产生不同的动作。多态性提供了同一个接口可以用多种方法进行调用的机制,从而可以通过相同的接口访问不同的函数。 本章讨论面向对象编程的核心问题继承与多态。通过继承,可以重用并扩展已有的类定义,创建新类。继承也是实现多态性的基础。多态性是面向对象编程的核心。下面的章节分别就这两个重要的问题展开。,59,8.1 继承的基本概念,第7章介绍了类的基本概念。类是一种自己定义的类型,用于满足应用程序的需求。把类的作用发挥出来的是继承,下面介绍继承。 继承的概念及重要性: 继承是软件重用的一种形式,将相关的类组织起来,并分享其间的公共通用的数据和操作行为。,60,8.2 继承和构造函数,类的继承是新的类从已有类那里得到已有的特性。由于继承当对子类进行初始化时,又牵涉到构造函数的调用。下面的小节分别就继承和构造函数进行讲解。,61,8.3 虚函数和多态性,虚函数是多态性的基础。在面向对象的概念中,多态性是指不同对象接收到相同消息时,根据对象类的不同产生不同的动作。多态性提供了同一个接口可以用多种方法进行调用的机制,从而可以通过相同的接口访问不同的函数。具体地说,就是同一个函数名称,作用在不同的对象上将产生不同的操作。,62,8.4 纯虚函数和抽象类,1纯虚函数 当在基类中不能为虚函数给出一个有意义的实现时,可以将其声明为纯虚函数,其实现留待派生类完成。 纯虚函数的作用是为派生类提供一个一致的接口。 2抽象类 带有纯虚函数的类称为抽象类。抽象类具有下述一些特点: 抽象类只能作为基类使用,其纯虚函数的实现由派生类给出;但派生类仍可不给出纯虚函数的定义,继续作为抽象类存在。 抽象类不能定义对象,一般将该类的构造函数说明为保护的访问控制权限。 可以声明一个抽象类的指针和引用。通过指针和引用,可以指向并访问派生类对象,进而访问派生类的成员,这种访问是具有多态特征的,63,8.5 接口与委托,托管C+中的接口最能体现COM接口的思想,有效的克服了不能多继承所带来的不便。而委托声明定义了一种使用特定签名来封装方法的引用类型。委托实例封装了静态或实例方法。委托大致与C+中的函数指针类似,但是,委托是类型安全的和可靠的。,64,8.6 装箱与拆箱,托管C+的类型总体上可分为值类型和托管类型。托管类型又称为引用类型,它具有垃圾自动回收功能。对于值类型,它又可分为内置类型(如Byte,Int32等)、自定义值类型和枚举类型。对于后两种类型,均有_value的关键字来修饰。 值类型虽不具有托管类型的优点,却可以提高应用程序的运行效率,因此在编写程序时应尽量减少使用托管类型,而多使用值类型。但是,为了实现跨语言的操作,需要将值类型转换成托管类型,而在本地应用时为了节省资源,又需要做相反的工作。 由值类型到托管类型的转换就是装箱,也就是说,装箱后的值类型可以用在任何托管代码中。由托管类型到值类型的转换称为拆箱,拆箱后在本地运行就可以提高效率。,窗体是图形用户界面的基本组成部分,也是VC+.NET可视化程序设计的基础,在应用程序中有着非常重要的位置。对于用户而言,窗体界面就是应用程序,用户感觉不到也不需要知道界面后面的代码,所以应用程序的可用性完全依赖于窗体界面。,第10章 Windows窗体设计,66,本章学习要点:,窗体的概念和作用 窗体的定位布局和属性 创建窗体的两种方法 常用控件的属性和事件及在程序中的作用 理解可见控件和不可见控件 CheckBox控件和RadioButton控件的异同 GroupBox控件和Panel控件的异同 Tab的顺序 事件的处理 对动态添加控件的事件的处理,67,10.1 设计窗体,Windows窗体是制作标准Win32屏幕的一种更高级的方法,具有非常健全的功能。.NET框架中的所有语言都使用Windows窗体来代替它们在图形窗体中所使用的组件。在.NET下Windows窗体为所有的语言提供了一套丰富、统一的控件和绘图功能,以及用于图形和绘图底层Windows服务的标准API。有了Windows窗体,任何图形和屏幕函数就不再需要使用内置的Windows图形接口了。 Windows窗体实际上是.NET框架基类的一部分,它使用的名称空间是System:Windows:Forms。在VC+.NET中并没有单独的“窗体模块”语法,窗体是一个类,所以它不能被隐含加载,即简单地通过引用一个窗体来加载它是无效的,必须创建该窗体再显示它。,68,10.2 创建窗体,在VC+.NET中,创建一个Windows窗体应用程序有两种方法:一种手动创建,一种是用项目模板来创建。无论怎样创建,都要用到.NET框架的System:Windows:Forms命名空间和System:Windows:Forms:Form类。,69,10.3 解决方案,现在对窗体已有了初步的认识,下面的小节是围绕一个完整的解决方案展开的。一些常用的控件,将在用到的时候细讲。下在看解决方案。 假定一个航班需要在乘客登机时跟踪乘客的信息,而且不同类型的飞机具有不同的座位配置。本章开发的应用程序的用途就是为两个不同的飞机配置创建座位表。 在应用程序的主窗体中,用户选择飞机类型并指定其他信息,如航班号,航班的出发站和到达站。应用程序利用用户指定的信息来显示一个包含座位表的窗体。在座位表窗体中,用户可以单击复选框来表示每个座位已经被占。在用户单击复选框时,窗体将会更新来指示已经被占的座位数和空座位数。,70,10.4 常用控件,控件作为.NET Framework类库的一部分出现在工具箱中,由所有的.NET语言共享。另外,组成.NET Framework的继承的类型按照层次结构组织,一个类型可以派生自另一个类型。控件派生自System:Windows:Forms:Control类。Control基类提供了键盘和鼠标输入的功能,以及为用户更新控件实例的显示的功能,10.5 Tab的顺序,一个窗体在运行时只有一个活动的控件实例。例如,当用户在文本框中输入文本时,文本框具有输入焦点,是活动的控件实例。Tab顺序表示用户按Tab键时窗体上的控件实例获得焦点的顺序。 每一个可以获得输入焦点的控件实例都支持TabIndex属性。可以通过为每一个可视的控件实例设置惟一的TabIndex属性值来定义Tab顺序。第一个获得焦点的控件的TabIndex值为0,第二个值为1,依次类推。,10.6 事件处理程序简介,在Windows应用程序中,用户操作(如单击鼠标或按某个键)、程序代码或系统内部都可以产生事件,这种基于事件驱动机制是目前实现用户交互的最好方法。在事件驱动机制中,应用程序代码可以响应事件来执行一系列的操作,称为事件处理。 在Visual C+.NET中,Windows窗体应用程序中的事件处理是通过委托来实现的。.NET框架中,Delegate类用于生成事件处理机制。一个委托是由对象的引用以及对该对象内一个或多个方法的引用组成的。,10.7 动态事件处理,在这章的解决方案中,由于两种型号飞机有不同的座位排数,所以动态创建了座位排数(即在其中动态加入CheckBox控件)。如果要对这些动态加入的控件产生的事件进行处理,就要用事件处理EventHandler,下面对它进行详细的介绍。 NET Framework中的事件处理是基于事件委托的。委托将事件与事件处理程序连接。引发事件需要两个元素: 标识对事件提供响应的方法的委托。 保存事件数据的类。 委托是一个定义签名的类型,即方法的参数列表类型。可以使用委托类型来声明一个变量,该变量可以引用与委托签名相同的所有方法。 事件处理程序委托的标准签名定义一个没有返回值的方法。该方法有两个参数,分别为sender和e,其中:参数sender,表示事件源。参数e,是不包含任何事件数据的EventArgs。其中第一个参数的类型为Object,它引用引发事件的实例,第二个参数从EventArgs类型派生,它保存事件数据。如果事件不生成事件数据,则第二个参数只是EventArgs的一个实例。否则,第二个参数为从EventArgs派生的自定义类型,提供保存事件数据所需的全部字段或属性。,10.8 解决方案的部分代码解释,这本章的解决方案包含有四个窗体,下面的就窗体为单位进行讲解。 1窗体flash,即闪屏。 2窗体Form1,主窗体。 3Airplane2窗体,座位情况窗体。 4提示窗体aboutWindow。这个窗体非常的简单,只需设置相应的属性就行了。,本章介绍如何创建多文档界面窗体(Multiple Document Interface,MDI)应用程序。将学习如何创建MDI父窗体(MDIParent)以及MDI子窗体(MDIChild)的其他窗体。另外,还将学习如何在MDI父窗体上添加工具栏和状态栏,父窗体和子窗体之间集成菜单,并且创建上下文菜单(快捷菜单)。,第11章 MDI程序设计,76,本章学习要点:,理解MDI应用程序的特征 组织MDI应用程序窗体之间的过程 理解MDI应用程序的标准窗体的作用 在MDI应用程序中集成菜单并创建上下文菜单 理解MDI应用程序的事件之间的关系 配置RichTextBox控件来显示自定义字体和颜色 使用RichTextBox控件读写文件 格式化一个RichTextBox控件实例 使用缩放 检测Web页的链接,77,11.1 MDI概述,在MDI应用程序中,每一个新的窗口都出现在另一个称为父窗体或父窗口的窗口中。MDI应用程序不是VC+.NET所特有的。实际上,像Word和Excel等应用程序都是MDI应用程序。,78,11.2 完整的解决方案,与前面各章不同的是,本章实现的解决方案使用了多文档界面。在MDI程序中,每一个新的窗口都出现在另一个称为父窗口的窗口中。本章创建的MDI应用程序将实现一个简单的字处理程序。,79,11.3 MDI的应用,本书前面开发的所有应用程序中创建的窗体都是可以出现在桌面的任意位置。这种类型的应用程序称为单文档界面。而本章主要地多界面的。 在创建MDI应用程序时,MDI父窗体及其子窗体具有不同于标准窗体的特征。首先,MDI窗体总是出现在父窗体的可视区域内。MDI子窗体不能超过父窗体。其次,当用户最小化MDI子窗体时,其图标默认时出现在父窗体的底部,而不是出现在任务栏中。图标化的MDI子窗体不会出现在任务栏。用户可以在MDI父窗体的任意位置定义图标。最后,当MDI子窗体最大化时,子窗体的标题出现在MDI标题栏的括号内。最大化的MDI子窗体占据了父窗体的整个可视区域,而不是整个桌面区域。如果用户最小化MDI父窗体,父窗体出现在任务栏上,而子窗体不会出现在任务栏上。,80,11.4 标准窗体的作用,MDI应用程序中的标准窗体通常显示为模态对话框,没有菜单。在本章的应用程序中,将把一个About窗体显示为标准窗体。,11.5 菜单和应用程序,在MDI程序运行时,如果子窗口包含有菜单,那么当子窗口被激活时,子窗口的菜单就会自动替换父窗口菜单;当子窗口被最小化时,在MDI父窗口里就会出现子窗口的图标。 每一个好的应用程序都包括了菜单这一部分内容,菜单不仅提供了在应用程序内进行导航(切换)的简单方式,还为处理应用程序提供了有用的工具,同时为用户提供了单击窗体上的按钮之外的方法来执行任务。菜单由显示为下拉式菜单的菜单栏组成包含菜单项和子菜单。,11.6 使用RichTextBox控件,本章主要利用RichTextBox控件实现文本编辑功能。RichTextBox控件用于显示、输入和操作格式文本。RichTextBox控件除了做TextBox控件做的每件事外,还可以显示字体、颜色和链接,从文件加载文本和嵌入的图像,撤消和重复编辑操作以及查找指定的字符。RichTextBox控件通常用于提供类似字处理程序(如Microsoft Word)的文本操作和显示功能。与TextBox控件一样,RichTextBox控件也可以显示滚动条;但与TextBox控件不同的是,默认情况下,它既显示水平滚动条又显示垂直滚动条,并且有更多的滚动条设置。,11.7 格式化富文本框,在这个解决方案中,用户将格式化出现在RichTextBox控件实例中的文本,方法是选择需要的文本,然后对它们应用希望的格式。在格式化富文本框时,有两个概念非常重要:插入点和选区。,11.8 缩放,使用Word时,可以任意缩放文档的内容。RichTextBox控件提供了相同的功能。ZoomFactor属性允许修改显示在RichTextBox控件实例中的文本的放大倍数。ZoomFactor属性为1时文本正常显示,为1.5时按照正常大小的1.5倍来显示,其他以此类推。,11.9 Web页链接,通过把DetectUrls属性设置为True,VC+.NET就可以自动地检测何时在RichTextBox控件实例中键入了URL(统一资源定位器,在这里可以理解为网址)。当检测到URL时,文本将醒目显示,并且加下划线。除了检测URL之外,还可以创建一个LinkClicked事件处理程序以便当用户单击URL进执行。 通常,当用户单击URL时,希望启动Web浏览器并且导航到该URL。要启动诸如Internet Explorer这样的程序,可以调用System:Diagnostics名称空间的Process类的Start方法。,本章将会介绍两项内容:一是目录、文件管理和文件操作,其中包括新建、删除目录,打开、读写顺序文件和随机文件等内容;二是介绍可用于托管C+的基本数据结构:ArrayList类、SortedList类、Queue类和Stack类。本章通过实现一个统一的解决方案来介绍以上内容,该解决方案除了应用本章介绍的主要知识之外,还需用到本书前面许多章节的知识,例如,托管结构和枚举的创建和使用、托管类的创建和使用、使用内置异常类处理异常等等。读者只要按照本章介绍的步骤实现该解决方案,就一定既能够很好地理解并学会运用本章介绍的主要知识,又能够巩固前面所学的许多知识。,第12章 文件操作与基本数据结构,87,本章学习要点:,了解System:IO命名空间 了解如何管理目录和文件 学会使用OpenFileDialog控件和SaveFileDialog控件 学会使用StreamReader类和StreamWriter类读写顺序文件 学会使用ArrayList类创建和管理数据列表 学会使用SortedList类创建和管理有序数据列表 学会创建先进先出列表(队列) 了解后进先出列表(堆栈) 学会使用FileStream类、BinaryReader类和BinaryWriter类打开和读写随机文件,88,12.1 预览解决方案,本章完整的解决方案包含多个窗体,每一个窗体都以不同的方式保存和管理类似的数据。例如,一个窗体以无序列表显示数据,另一个窗体则以有序列表显示数据。一个窗体管理队列,另一个窗体则允许查看文件属性。下面列出了组成解决方案的窗体及其作用。,89,12.2 了解System:IO命名空间,为进行数据的输入输出操作,.NET Framework把不同的输入、输出源(文件、键盘、网络连接、内存等)抽象为“流”(Stream)。要在托管C+程序中进行文件处理,必须引用命名空间System:IO。System:IO命名空间提供了用来管理目录(文件夹)和文件,以及以各种方式读取和写入文件的类。,90,12.3 目录与文件管理,System:IO:Directory类包含了管理Windows文件系统的共享方法,因此在调用其方法之前不必创建该类的实例。在使用System:IO:Directory 类时,必须理解当前工作目录的概念,在应用程序运行时,某一时刻只能有一个当前工作目录。如果对目录或者文件使用相对引用,VC+.NET将会使用当前目录作为相对引用的开始;如果使用绝对引用,则忽略当前工作目录。管理文件可使用System:IO:File类,它与Directory类具有相似的操作方式。,91,12.4 使用OpenFileDialog和SaveFileDialog控件,在任何涉及文件管理的应用程序中,都必须给用户提供一种方式进行文件打开或者保存。在VC+.NET中可以使用OpenFileDialog控件和SaveFileDialog 控件来实现这一功能,它们允许用户使用标准的对话框选择文件然后打开或保存。这两个对话框允许用户通过在文件系统中进行导航(查询目录树)来选择目录,然后选择文件并打开或者保存。这两个控件不会实际打开和保存文件,它们只是为用户提供了选择文件的方式,由程序员在应用程序中编写代码来实际打开和保存选择的文件,12.5 读写顺序文件,VC+ .NET提供了灵活的读写文件的功能,可以使用不同类的多种方法获得相同的结果。本节介绍一种向磁盘读写顺序文件的方式。 文件可以大致分为两种: 顺序文件(Sequential file):该类文件包含不同长度的记录,通常由换行符分隔这些记录。每一个记录包含一个或者多个域,由分隔符分隔域,分隔符通常是逗号,也可以是其他字符。 随机文件(Random file):也称为直接访问文件,通常是二进制文件。随机文件中的记录具有固定的大小,因此可以直接访问某个记录而不必读取它前面的记录。随机文件的执行性能高,因为可以直接读取和操作需要的记录。本章的第10节将会讨论随机文件。,12.6 ArrayList类,ArrayList类属于集合的一种,首先介绍一下集合。 集合(collection)由多个通常是相同类型的对象以某种方式组织在一起。在本章的解决方案中,将读取表示对呼叫中心的呼叫的顺序文件,并且总结其内容。不管集合管理的对象类型是什么,任何集合都提供了枚举集合中的对象的方式。集合常见的数据结构包括列表(ArrayList类)、有序列表(SortedList类)、堆栈(Stack类)和队列(Queue类)。程序员可以通过重写已有的集合功能来创建自己的集合。 所有预定义的.NET集合类都属System:Collections名称空间,该名称空间中的类允许以不同的方式实现集合。上面列出的类可以使用任何类型的对象,也就是说,它们都使用包含System:Object类型的项目列表。如果启用了严格类型检查,必须把通用的System:Object类型转换为特定的类型。,12.7 SortedList类,SortedList类与数组和数组列表类似,它保存的也是对象列表,但它自动地以排序顺序维护元素。SortedList类在内部维护了两个数组,一个数组保存键标,键标用来定位与其相关联的值;另一个数组保存值。SortedList类允许在给定键标的情况下直接从列表中检索值,并且可以方便地从列表中添加和删除项目。 图12-10 SortedList类中键标和值的关系,12.8 队列,队列列表的方式与ArrayList相似,但是队列是一种先进先出的数据结构。第一个添加到队列中的项目也是第一个从队列中删除的项目,也即,元素添加到队列的底部,而从队列的顶部删除。如果对呼叫中心的呼叫速度超过了处理速度,将会把需要等待的呼叫保存在队列中。 图12-2 队列的操作,12.9 堆栈,堆栈是后进先出的列表,最后添加到堆栈中的项目将会最先从堆栈中删除。 图12-12 堆栈的操作图,12.10 打开与读写随机文件,对随机文件进行操作实际上是对文件中的记录进行操作,每个记录都有记录号并且记录长度全都相同。本节将打开一个随机文件进行读写,随机文件中包含呼叫中心工作人员的如下记录:编号、姓名、住址、休假天数、病假天数。在VC+.NET中,对随机文件的操作可通过FileStream类、BinaryReader类和BinaryWriter类进行。,第13章 ADO.NET,在当今信息化社会数据库已经被普遍使用,对人们的日常生活也越来越来重要。并因此出现了许多数据库管理系统,如Microsoft Access、Microsoft SQL Server、Oracle、Microsoft Visual Foxpro等。尽管这些系统能出色完成数据库中数据的管理但它们为了通用性,不是根据人们的实现业务需求而设计。这就需要需要重新设计一种应用程序来完成人们的实现业务需求,并将业务活动过程中产生的数据保存到数据库。ADO.NET就是在.NET环境下,应用程序访问数据库的一种途径。,99,本章学习要点:,了解ADO.NET模型 了解OleDbConnection 使用OleDbDataAdatper 理解DataSet 修改DataTable中的数据 参数化查询 简单的数据绑定 DataGrid控件的基本使用 了解DataReader,本章将创建一个对数据库进行访问的解决方案StudentInfo。要访问的数据库为SQL Server中名为“学生信息管理”的数据库。 图13-1 学生信息管理数据库,13.1 学生信息管理系统,101,13.2 ADO.NET模型,ADO.NET是在.NET Framework环境中用于访问数据库的一组组件类。ADO.NET以两种模式工作:非连接模式和连接模式。其中,在连接模式下,程序开发者创建对数据库的连接,然后把命令发送到连接,再由连接将命令传递到数据库,最后将数据库返回的数据保存到一个ADO.NET中的DataReader组件;而在非连接模式下,数据库返回的数据被保存到ADO.NET中的DataSet组件中,而DataSet组件允许程序开发者从数据库检索数据,离线处理,然后创建新连接把修改发送回数据库。,102,13.3 OleDbConnection,要使用ADO.NET从数据库检索数据和发送数据库操作命令,必须首先创建对数据库的连接。在建立连接后,就可以通过连接向数据库发送操作命令。操作命令由另一个被称为提供器的软件组件处理。提供器根据接收到的命令,对数据库进行检索或更新操作,如果数据库有返回结果,则结果再通过OleDbConnection组件返回。图13-5演示了连接器、提供器和数据库之间的关系。 图13-5 连接关系,103,13.4 OleDbDataAdapter,OleDbDataAdapter组件通过连接把SQL语句发送给提供器进行处理。提供器返回对数据库进行查询后得到的数据给OleDbDataAdapter。返回的数据再由OleDbDataAdapter填充DataSet组件。在查询未返回数据的情况下,提供器将会返回请求操作是否成功。 图13-6 OleDbDataAdapter的作用,104,13.5 DataSet结构,DataSet类是ADO.NET的主要组件,它是从数据库中检索到的数据在内存中的缓存。DataSet由一组DataTable对象组成,实际的数所保存到DataTable对象。,13.6 修改DataTable中的数据,到目前为止,我们实现了查看数据库表中的记录。接下来将介绍如何通过修改DataTable中的记录,从而修改与它相连的数据库。由于DataSet和其DataTable工作在非连接模式下,因此对DataTable中记录的修改不会自动地保存回数据库。,13.7 参数化查询,前面已经介绍了如何使用SQL SELECT语句从数据库表返回所有记录。但是,如果只想检索某个记录或者某些符合条件的记录,并且希望能够根据用户的输入检索这些记录,这是就就需要创建一个参数化的SQL语句。 首先,请看下面的SQL语句,它用于检索指定的某个记录: SELECT * FROM 学生信息表 WHERE 学号=? 在前面的SELECT语句中,WHERE子句定义了一个条件。其中问号“?”定义了一个参数的占位符。这样,只有那些 “学号”列的值与参数值相同的行才会从数据库表返回。在定义了参数的占位符后,必须提供一种方法在该占位符中保存数据。为此需要使用OleDbParameter类。,13.8 更新数据库,由于DataSet及其中的DataTable处于非连接模式,因此必须使用OleDbDataAdapter显式地把修改保存到数据库。 下面列举了几个与保存数据到数据库有关的成员: OleDbDataAdapte的InsertCommand,UpdateCommand和DeleteCommand属性包含分别用来添加、修改和删除记录的SQL语句。 OleDbDataAdapter的Update方法为DataSet中每个已插入、已更新或已删除的行调用相应的INSERT、UPDATE或DELETE语句。 RowState属性标记某个DataRow是否新添加、修改或者被删除。OleDbDataAdapter使用该信息来确定要更新的数据库表中的行。 OleDbDataAdapter通过OleDbConnection发送合适的参数化SQL语句来记录添加、修改和删除。,13.9 自动创建ADO.NET组件,在前面所介绍的内容中,我们使用手工编辑的方式创建并配置了ADO.NET组件,实现了对数据库的访问和操作。其实,在.NET环境中,更常用访问数
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 图纸专区 > 课件教案


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!