第1 2章 动态对象创建

合集下载

第一章 直流电动机的数学模型及其闭环控制系统

第一章 直流电动机的数学模型及其闭环控制系统
直流电源电压;C为滤波电容器;VT为功率开关器件; VD为续流二极管;MD为直流电动机。
图 1-10 PWM控制器与变换器的框图
图1-9不可逆PWM变换器—直流电动机系统
结合PWM变换器工作情况可以看出:当控制 电压变化时,PWM变换器输出平均电压按线性规 律变化,因此,PWM变换器的放大系数可求得, 即为
4.直流调速系统的广义被控对象模型
(1)额定励磁状态下直流电动机的动态结构图 图1-12所示的是额定励磁状态下的直流电动机动 态结构图。
图1-12 额定励磁状态下直流电动机的动态结构框图
由上图可知,直流电动机有两个输入量,一个是施加在电枢
上的理想空载电压U d0 ,另一个是负载电流 I L 。前者是控制输入量,
它已不起作用,整流电压并不会立即变化,必须等
到 t3时刻该器件关断后,触发脉冲才有可能控制另
一对晶闸管导通。
设新的控制电压
U ct2
U
对应的控制角为
ct1
2 1 ,则另一对晶闸管在 t4 时刻导通,平均整
流电压降低。假设平均整流电压是从自然换相点
开始计算的,则平均整流电压在 t3 时刻从U d01降
Tm
GD2 R
375K
e
K
m
2 d
(1-23)
因其中d 的减小而变成了时变参数。由此 可见,在弱磁过程中,直流调速系统的被控对象 数学模型具有非线性特性。这里需要指出的是, 图1-15所示的动态结构图中,包含线性与非线性 环节,其中只有线性环节可用传递函数表示,而 非线性环节的输入与输出量只能用时域量表示, 非线性环节与线性环节的连接只是表示结构上的 一种联系,这是在应用中必须注意的问题。
Ks
U d U ct

《计算机控制技术》复习思考题 第1章 第2章

《计算机控制技术》复习思考题 第1章 第2章

《计算机控制技术》复习思考题第一章自动控制系统基本概念1.自动控制系统的组成一个简单的自动控制系统,均可概括成两大部分:一部分是自动化装置控制下的生产设备,称为被控对象;另一部分是为实现自动控制所必须的自动化仪表设备,简称为自动化装置,它包括测量变送器、调节器和执行器等。

简单的自动控制系统由被控对象、测量变送器、调节器及执行器四大部分组成。

2.术语a)被控对象?调节器?执行器?测量变送器?b)被控变量,y?设定值,g?测量值,z?偏差,e?干扰,f?调节参数?在被控对象中,需要控制一定数值的工艺参数叫做被控变量,用字母y表示。

被控变量的测量值用字母:表示,按生产工艺的要求,被控变量希望保持的具体数值称为设定值,用字母譬表示。

被控变量的测量值与设定值之间的差值叫做偏差,用字母e表示,e=g-z。

在生产过程中,凡能影响被控变量偏离设定值的种种因素称为干扰,用字母,表示。

用来克服干扰对被控变量的影响,实现控制作用的参数叫做调节参数。

c)反馈?负反馈、正反馈?把系统(或环节)的输出信号直接或经过一些环节重新返回到输入端的做法叫做反馈。

如果反馈信号能够使原来的信号减弱,也就是反馈信号取负值,那么就叫做负反馈。

如果反馈信号取正值,反馈信号使原来的信号加强,那么就叫做正反馈。

自动控制系统绝对不能单独采用正反馈。

d)闭环系统?一个一个信号沿着箭头的方向传送,最后又回到原来的起点,形成一个闭合的回路,如此循环往复,直到被控对象的被控变量值达到或接近设定值为止,所以这种自动控制系统是闭环系统。

自动控制系统是具有被控变量负反馈的闭环系统。

3.自动控制系统方框图?4.自动控制系统的分类?按照工艺过程需要控制的参数值即设定值是否变化和如何变化来分类,而将闭环自动控制系统分为定值控制系统、随动控制系统和程序控制系统三大类。

按调节器具有的控制规律来分类,如位式、比例、比例积分、比例微分、比例积分微分等控制系统。

定值控制系统、随动控制系统和程序控制系统?5.过渡过程a)静态、动态?自动控制系统的平衡(静态)是暂时的、相对的和有条件的,不平衡(动态)才是普遍的、绝对的、无条件的。

自动控制原理第1章

自动控制原理第1章
31
⑴ 稳定性 稳定性是保证控制系统正常工作的先决条件.
稳定性是这样来表述的:系统受到外作用后,其动态过程的振荡倾向和 系统恢复平衡的能力。
线性自动控制系统的稳定性是由系统的结构和参数所决定, 与外界因素和初始条件无关.
不稳定系统是无法正常工作的。
c(t) r(t)
c(t ) r (t )
c(t) r(t)
③ 可以完成人工控制系统无法完成的工作。
自动控制已成为现代社会活动中不可缺少的重要组成部分。
6
比如:人造地球卫星的
发射成功与安全返回
7
导弹的准确击中目标, 雷达系统的准确跟踪目标;
8
交通系统:
安全、快捷、舒适、准点
9
钢 铁 生 产
10
家用电器:
电扇:控制转速
洗衣机:控制水位、强弱、时间等
23
⑶ 复合控制方式 把按偏差控制和按扰动控制结合起来,是一种比较合理的控 制方式.这种按偏差控制和按扰动控制相结合的控制方式称为复 合控制方式. 下图表示的是电动机速度的复合控制系统的方块图. 电压 放大器 电阻R Mc
u0 ut -
ue
电压 放大器
测速 发电机
功率 放大器
电动机
n
图1-10 电动机速度复合控制系统
1.1 自动控制的基本概念与方式
1.2 自动控制系统的分类 1.3 对控制系统性能的基本要求及评价
5
1.1 自动控制的基本概念与方式
1.1.1 自动控制的基本概念
自动控制:在没有人直接参与的情况下,通过控制器,
使被控对象或过程自动地按预定的规律运行。 应用:工业、农业、交通、国防、宇航、社会。 自动控制的优点:① 节省人力; ② 提高系统的精度;

教育管理原理-第一讲-(第1-2章)练习题

教育管理原理-第一讲-(第1-2章)练习题

教育管理原理-第一讲-(第1-2章)练习题1.管理具有两重性,即() [单选题] *A.文化性与非文化性的统一B.经济性与非经济性的统一C.非政治性与政治性的统一(正确答案)D.一般性和特殊性的统一2. 年中国设立了学部,后改称教育部。

() [单选题] *A.1949B.2000C.1905(正确答案)D.19103.日本的中小学设立“教员意见登记簿”,鼓励教员对学校管理工作提出意见,到期末,须对教员的意见给予答复,意见采纳了的要予以表扬,未被采纳的要说明原因。

这反映了教育管理发展趋势的() [单选题] *A.民主化(正确答案)B.科学化C.均权化D.专业化4.教育管理的特殊规律包括()①教育管理活动的规律②教育管理体制的规律③教育管理机制的规律④教育管理观念的规律 [单选题] *A.①②③B.②③④C.①②④D.①②③④(正确答案)5.学科体系包括() [单选题] *A.一门学科和学科群B.著作体系和著作层次体系C.著作体系和教材体系(正确答案)D.著作层次体系和教材层次体系6.现代教育管理学的两大源流是()①德国的行政学②美国的行政学③法国的行政学④中国的行政学 [单选题] *A.①②(正确答案)B.②③C.①④D.③④7.人际关系理论,是等在霍桑工厂里通过实验而创立的理论。

() [单选题] *A.梅奥和雷斯利斯伯格(正确答案)B.卡伯利和梅奥C.泰勒和雷斯利斯伯格D.巴纳德和西蒙8.教育管理学在我国作为独立形态的学科始于() [单选题] *A.中华人民共和国成立B.改革开放C.19世纪初D.19世纪末20世纪初(正确答案)9.库恩提出了的概念,不主张用数学概念来阐述理论,而是借助历史材料来构建理论() [单选题] *A.变式B.范式(正确答案)C.实证主义D.思辨哲学10.管理具有两重性,其中,管理与生产力和社会化大生产相联系的属性我们称之为() [单选题] *A.非政治性(正确答案)B.政治性C.经济性D.复杂性11.目前在美国的各大学普遍设有教育管理专业,培养教育管理方面的专业人员。

第1章 什么是动态网页技术

第1章 什么是动态网页技术

ASP简单示例
PHP
Rasmus Lerdorf 1994年提出,经过其他人 参与,共同开发而成。 服务器端:Unix,Linux,或者Windows操 作系统下;客户端:普通浏览器。 特点: 优点:免费、开放源代码;缺点:缺乏大 公司的支持。

JSP( Java Server Pages)

.NET技术

.NET技术到底是什么?如果说互联网是一 个信息海洋,那么.com就是信息海洋中的 “数字孤岛”。将这些数字孤岛连接起来, 打破不同的上网设备、不同的操作系统、 不同的网站以及各大机构和工业界的网络 障碍,从而实现互联网的全部潜能,这就 是微软的 .NET的核心内容
.NET技术—核心内容



相对于ASP来说,具有了很多特性: 提供了更易于编写、结构更清晰的代码, 容易进行再利用和共享; 使用编译后的语言,从而提升性能和伸 缩性;使用Web表单使开发更直观,利 用面向对象技术促进组件的再利用。 另外,中还包括有页面事件、Web控件、 缓冲技术以及服务器控件和对数据捆绑的改进。
4. Active Server Pages模型
当浏览器向Web服务器请求.asp文件时,服务器端脚 本便开始运行。Web服务器于是调用ASP,用它从头至尾 处理所请求的文件、执行脚本命令,并将Web页发送到浏 览器。 因为脚本运行于服务器而不是客户端,所以生成发 送到浏览器的HTML页等工作便由Web服务器负责。服务器 端脚本无法被预先复制,因为返回到浏览器的只是脚本 的运行结果。用户无法得知创建其所查看的页面使用的 脚本命令。
J2EE技术



J2EE(Java 2 Platform Enterprise Edition)是一种 利用Java 2平台来简化诸多与多级企业解决方案的 开发、部署和管理相关的复杂问题的体系结构。 J2EE技术的基础就是核心Java平台或Java 2平台的 标准版,J2EE不仅巩固了标准版中的许多优点, 例如“编写一次、到处运行”的特性、方便存取 数据库的JDBC API、CORBA技术以及能够在 Internet应用中保护数据的安全模式等等; 还提供了对 EJB(Enterprise JavaBeans)、Java Servlets API、JSP(Java Server Pages)以及XML 技术的全面支持。

种群数量的变化(第一课时)高二生物(人教版2019选择性必修2)

种群数量的变化(第一课时)高二生物(人教版2019选择性必修2)
(3)为什么大草履虫种群没有出现“J” 形增长?
由于随着大草履虫数量的增多,对食 物和空间的竞争趋于激烈,导致出生 率下降,死亡率升高。
(4)这种类型的种群增长称为什么?
种群的“S”形增长
二、种群的“S”形增长
合作探究十一:自主学习课本P9页相关内容,请小组合作完成以下 问题。
1.什么是“S”形增长曲线? 2.“S”形增长曲线形成原因是什么? 3.“S”形增长曲线的适用对象是什么? 4.“S”形增长曲线的增长特点。 5.尝试分析“S”形增长曲线各段的含义。 6.什么是环境容纳量(K值)?如何运用?
实战训练
5.图1为植食性昆虫迁入该生态系统后的种群数量增长速率变化曲 线,图2为λ(λ是当年种群数量与前一年种群数量的比值)随时 间的变化曲线。下列有关叙述,正确的是( )
A.图1中t1~t2与图2中a~b时期种群都是衰退型 B.图2中a、c时期种群的出生率均与死亡率相当
C.图1和图2中K值出现的时间分别是t2和d
研究 方法
观察分析 提出问题
做出假设
建立 数学模型
对模型进行 检验修正
研究 细菌每20min分裂
一次,怎样计算
实例 繁殖n代的数量?
在资源和生存空间没 有限制的条件下,细 菌种群的增长不会受 种群密度增加的影响
Nn=2n N代表细菌数 量,n表示第 几代
观察、统计细菌 数量,对模型进 行检验或修正
一、建构种群增长模型的方法 建立数学模型
细菌的增殖(视频)
我们的手上难免沾染细菌。细 菌的繁殖速率很快,因而我们要常 洗手。假设在营养和生存空间没有 限制的情况下,某种细菌每20min 就通过分裂繁殖一代。
合作探究一:细菌的生殖方式是怎样的? 二分裂

VB测试题1-2章

VB第一章测试题(1)1、激活主菜单的按键是()A.F1或Ctrl键 B.Ctrl键或Atl键C.F10或Ctrl键 D.F10或Atl键2.如果设计时在属性窗口将命令按钮的()属性设置为False,则运行时按钮从窗体上消失.A.Visible B.EnabledC.DisabledPicture D.Default3.退出Visual Basic的快捷键是()A.Ctrl +Q B.Shift +QC.Alt+Q D.Ctrl+Alt+Q4.除了系统默认的工具箱布局外,在Visual Basic中还可以通过()方法来定义选项卡组织安排控件.A.在工具箱单击鼠标右键,执行快捷菜单中的“添加选项卡”命令B.执行“文件”菜单中的“添加工程”命令C.执行“工程”菜单中的“添加窗体”命令D.执行“工程”菜单中的“部件”命令5.窗体设计器是用来设计()A.应用程序的代码段 B.应用程序的界面C.对象的属性 D.对象的事件6.启动Visual Basic后,系统为用户新建的工程起一个名为()的临时名称.A.工程1 B.窗体1C.工程 D.窗体7.工程资源管理器窗口中包含的文件类型有()种.A.2 B.3C.4 D.58.Visual Basic的编程机制是()A.可视化 B.面向对象C.面向图形 D.事件驱动9.Visual Basic集成环境的大部分窗口都可以从主菜单项()的下拉菜单中找到相应的打开命令.A.编辑 B.视图C.格式 D.调试10.要在窗体上显示图片,需设置窗体的()属性.A.Caption B.IconC.Picture D.ControlBox11.每个窗体对应一个窗体文件,窗体文件的扩展名是()A..bas B..clsC..frm D..vbp12.双击窗体的任何地方,可以打开的窗口是()A.代码窗口 B.属性窗口 C.工程管理窗口 D.以上3个选项都不对13.工具栏中的“启动”按钮的作用是()A.运行一个应用程序 B.运行一个窗体C.工程管理窗口 D.打开被选中对象的代码窗口14.运行时,单击窗体将窗体的前景色设置为红色的事件过程是()A. Private Sub Form_Click( ) B.Private Sub Form_Click( )BackColor=vbRed Form1.ForeColor=vbRedEnd Sub End SubC.Private Sub Form_Click( ) D.Private Sub Form_Click( )Form1.BackColor=vbRed ForeColor=vbRedEnd Sub End Sub15.如果要在命令按钮上显示图形文件,应设置命令按钮的()A.Style属性和Graphics属性 B.Style属性和Picture属性C.Picture属性D.Graphics属性16.英文缩写OLE的含义是()A.面向对象程序设计 B.对象链接C.对象嵌入 D.对象链接与嵌入17.在设计阶段,双击窗体Form1的空白处,打开代码窗口,显示()事件过程模板.A.Form_Click B.Form_Load C.Form1_Click D.Form1_Load18.每建立一个窗体,工程管理器窗口中就会增加一个()A.工程文件 B.窗体文件C.程序模块文件 D.类模块文件19.激活属性窗口使用的键是()A.F2 B.F3 C.F4 D.F520.Visual Basic是一种()程序设计语言.A.过程式 B.非过程式C.机器 D.低级21.不能在运行期间设置窗体的()属性.A.BorderStyle B.Caption C.Icon D.MaxButton22.设在窗体上有两个命令按钮,其中一个命令按钮的名称为cmda,则另一个命令按钮的名称不能是()A.cmdc B.cmdb C.cmdA D.Command1二、填空题1. 如果要在单击钮时执行一段代码,则应将这段代码写在_______________事件过程中.2. 一个工程可以包括多种类型的文件,其中,扩展名为.vbp的文件表示___________文件;扩展名为.frm的文件表示_____________文件;扩展名为.bas的文件表示_____________文件;包含ActiveX控件的文件扩展名为__________.3. Visual Basic 6.0用于开发__________环境下的应用程序.如果要使用命令按钮表面显示文字“退出(X)”(在字符X之下加下划线),则其Caption属性设置为___________,其括号中的X表示在运行时按下____________键与单击该按钮效果相同.打开“工程窗口”的方法之一是按下______________组合键.Visual Basic的控件通常分为3种类型,即___________、___________、____________.其中,____________不能从工具箱中被删除,_____________单独保存在.OCX文件中,在必要进可以加入到工具箱中.VB第一章测试题(2)一、选择题1. 标准模块文件的扩展名为_________。

过程控制 第一到三章 作业

第一章作业1.1 常用的评价控制系统动态性能的单项性能指标有哪些?它与误差积分指标各有何特点?答:(1)衰减率ψ、超调量σ、稳态误差e ss、调节时间t s、振荡频率ω;(2)单项指标用若干特征参数评价系统优劣,积分指标用误差积分综合评价系统优劣。

1.2 什么是对象的动态特性?为什么要研究对象的动态特性?答:(1)指被控对象的输入发生变化时,其输出(被调量)随时间变化的规律;(2)实现生产过程自动化时,对象的动态特性可以为控制工程师设计出合理的控制系统满足要求提高主要依据。

1.3 通常描述对象动态特性的方法有哪些?答:微分方程或传递函数。

1.4 过程控制中被控对象动态特性有哪些特点?答:无振荡、稳定或中性稳定、有惯性或迟延、非线性但在工作点附近可线性化。

1.11 某水槽水位阶跃响应实验为:其中阶跃扰动量Δµ=20%。

(1)画出水位的阶跃响应曲线;(2)若该水位对象用一阶惯性环节近似,试确定其增益K和时间常数T。

解:MATLAB编程如下:%作出标幺后的响应曲线t=[ 0 10 20 40 60 80 100 150 200 300 400 ];h=[ 0 9.5 18 33 45 55 63 78 86 95 98 ];x=0:0.01:400;y=interp1(t,h,x,'spline'); %三次样条函数据己知的t、h插出x的值yy=y/y(end); %输出标幺plot(x,yy,'k');xlabel('t/s');ylabel('h/mm');title('阶跃响应曲线','fontsize',10);grid;%找出最接近0.39和0.63的点 less1=find(yy<=0.39); more1=find(yy>=0.39); front1=less1(1,end); behind1=more1(1,1);cha11=0.39-yy(1,front1); cha12=yy(1,behind1)-0.39; if cha11<=cha12 t1=x(1,front1) elset1=x(1,behind1) endless2=find(yy<=0.63); more2=find(yy>=0.63); front2=less2(1,end); behind2=more2(1,1);cha21=0.63-yy(1,front2); cha22=yy(1,behind2)-0.63; if cha21<=cha22 t2=x(1,front2) elset2=x(1,behind2) end%求增益K 和时间常数T K=y(end)/20 T=2*(t2-t1)(1)水位的阶跃响应曲线如图:t/sh /m m阶跃响应曲线(2)计算结果如下:>> GK1_11 t1 =48.1700t2 =96.5900K =4.9T =96.8400则该水位对象用一阶惯性环节近似后,得其增益K=4.9,时间常数T≈96.84。

第(1)(2)章自测练习答案

第一章自测练习一、单项选择:1、管理的首要职能是()。

A、计划B、控制C、协调D、指挥2、下列各选项中,()属于管理的对象。

A、组织资源和组织目标B、组织资源和组织活动C、组织目标和组织活动D、组织中的人3、在管理的各项职能中,最具有规范性、技术性的职能是()。

A、计划B、组织C、领导D、控制4、管理的职能分为一般职能和()。

A、指挥职能B、计划职能C、具体职能D、控制职能5、“管理就是决策”是()的观点。

A、泰罗B、法约尔C、西蒙D、韦伯6、“凡事预则立,不预则废”,说的是()的重要性A、组织B、预测C、预防D、计划7、人们常说“管理是一门艺术”。

强调的是()。

A、管理的实践性B、管理的复杂性C、管理的科学性D、管理的变动性8、在管理的各项职能中,()职能能够保证目标及为此而制订的计划得以实现。

A、领导B、协调C、控制D、计划9、组织是管理的基本职能之一,它由()三个基本要素组成。

A、目标、原则和结构B、目标、部门和效率C、目标、部门和关系D、目标、部门和人员。

10、为了保证计划目标得以实现,就需要有控制职能,控制的实质就是使()。

A、实践活动符合于计划B、计划接近实践活动C、实践活动具有指标约束D、计划得以严格执行11、就管理的职能而言,法约尔认为()。

A、管理就是实行计划、组织、指挥、协调和控制B、管理就是要确切地知道要别人干什么,并注意他们用最好最经济的方法去干C、管理就是决策D、管理就是经由他人去完成一定的工作。

12、当管理者接待来访者、参加剪彩仪式等社会活动是,他扮演的是()A、发言人B、组织联络者C、领导者D、精神领袖13、对于基层管理者来说,具备良好的()是最为重要的。

A、人际技能B、概念技能C、技术技能D、管理技能14、对于高层管理者来说,具备良好的()是最为重要的。

A、人际技能B、概念技能C、技术技能D、管理技能二、多项选择1、管理作为一种特殊的实践活动,具有其独特的性质,比如()A、管理具有二重性B、管理具有科学性C、管理具有艺术性D、管理具有时效性2、根据管理二重性的原理,管理具有同()相联系的自然属性A、生产力B、生产关系C、社会化大生产D、社会制度3、关于高层、中层和基层管理者三者之间的关系,可以描述为()A、他们所履行的管理职能是相同的B、高层管理者花在计划职能上的时间要比基层管理者多C、高层管理者花在控制职能上的时间要比基层管理者少D、基层管理者花在领导职能上的时间要比高层管理者多4、明茨伯格通过实证研究发现,管理者在组织中扮演十种角色,这些角色被分为()A、人际关系角色B、组织角色C、信息角色D、决策角色5、下列选项中,()属于管理者所扮演的决策角色。

C++面向对象程序设计ppt课件第1章


面向对象方法学概述
传统的软件开发方法采用结构化技术(结构化分析、结构 化设计和结构化实现)来完成软件开发的各项任务,强调 的是将一个较为复杂的任务分解成许多易于控制和处理的
子任务,自顶向下顺序地完成软件开发各阶段的任务。
面向对象方法学就是尽量模拟人类习惯的思维方式,使软 件开发的方法与过程尽可能接近人类认识世界、解决问题 的方法与过程,从而使描述问题的问题空间(即问题域)与 实现解法的解空间(即求解域)在结构上尽可能一致。
从C到C++
[例1-1] 从C到C++的实例——学生成绩管理。
使用数组 使用结构体 类 struct Student { long lNum; //学号 char cName[12]; //姓名 float fGrade; //成绩 }; class OurClass //声明一个班级类 { Student s[N]; //定义N个学生 void Input(); //输入学生信息 void Print(); //输出学生信息 void Sort(); //按学生成绩进行排序 };
图1-2 继承关系
图1-3 单继承
图1-4 多继承
面向对象程序设计的特点
多态性
多态性是面向对象方法的重要特征。不同的对象,收到同一消息可以产生不 同的结果,这种现象称为多态性。 例如,一个学生拿着象棋,对另一个学生说:“咱们玩棋吧。”
一个小朋友拿着跳棋对另一个小朋友说:“咱们玩棋吧。”
成类。
例如,挪开凳子,人类处理问题的过程是拿起凳子,移到一边。 面向过程的思想是将凳子和挪开作为两个实体来对待(描述凳子的数据和 移动凳子的动作); 面向对象的思想是选择一个对象——凳子,然后向这个对象施加一个动 作——挪开。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

下载下载第1 2章动态对象创建有时我们能知道程序中对象的确切数量、类型和生命期。但情况并不总是这样。空中交通系统必须处理多少架飞机?一个C AD系统需要多少个形状?在一个网络中有多少个节点?为了解决这个普通的编程问题,在运行时能创建和销毁对象是基本的要求。当然,C已提供了动态内存分配函数malloc( )和free( )(以及malloc( )的变种),这些函数在运行时从堆中(也称自由内存)分配存储单元。然而,在C ++中这些函数不能很好地运行。构造函数不允许通过向对象传递内存地址来初始化它。如果那么做了,我们可能1) 忘记了。则对象初始化在C ++中难以保证。2) 期望某事发生,但结果是在给对象初始化之前意外地对对象作了某种改变。3) 把错误规模的对象传递给了它。当然,即使我们把每件事都做得很正确,修改我们的程序的人也容易犯同样的错误。不正确的初始化是编程出错的主要原因,所以在堆上创建对象时,确保构造函数调用是特别重要的。C ++是如何保证正确的初始化和清理并允许我们在堆上动态创建对象的呢?答案是使动态对象创建成为语言的核心。malloc( )和free( )是库函数,因此不在编译器控制范围之内。如果我们有一个能完成动态内存分配及初始化工作的运算符和另一个能完成清理及释放内存工作的运算符,编译器就可以保证所有对象的构造函数和析构函数都会被调用。在本章中,我们将明白C ++的n ew和d elete是如何通过在堆上安全创建对象来出色地解决这个问题的。

12.1 对象创建当一个C ++对象被创建时,有两件事会发生。1) 为对象分配内存。2) 调用构造函数来初始化那个内存。到目前为止,我们应该确保步骤2)一定发生。C ++强迫这样做是因为未初始化的对象是程序出错的主要原因。不用关心对象在哪里创建和如何创建的—构造函数总是被调用。然而,步骤1)可以以几种方式或在可选择的时间内发生:1) 静态存储区域,存储空间在程序开始之前就可以分配。这个存储空间在程序的整个运行期间都存在。2) 无论何时到达一个特殊的执行点(左花括号)时,存储单元都可以在栈上被创建。出了执行点(右花括号),这个存储单元自动被释放。这些栈分配运算内置在处理器的指令集中,非常有效。然而,在写程序的时候,必须知道需要多少个存储单元,以使编译器生成正确的指令。3) 存储单元也可以从一块称为堆(也可称为自由存储单元)的地方分配。这称为动态内存分配,在运行时调用程序分配这些内存。这意味着可以在任何时候分配内存和决定需要多少内存。我们也负责决定何时释放内存。这块内存的生存期由我们选择决定—而不受范围限制。这三个区域经常被放在一块连续的物理存储单元里:静态内存、堆栈和堆(由编译器的作者决定它们的顺序),但没有一定的规则。堆栈可以在某一特定的地方,堆的实现可以通过调用由运算系统分配的一块存储单元来完成。对于一个程序设计者,这三件事无须我们来完成,所以我们所要思考的是什么时候申请内存。

12.1.1 C从堆中获取存储单元的方法为了在运行时动态分配内存,C在它的标准库函数中提供了一些函数:从堆中申请内存的函数malloc( )以及它的变种calloc( )和realloc( );释放内存返回给堆的函数free( )。这些函数是有效的但较原始,需要编程人员理解和小心使用。对使用C的动态内存分配函数创建一个类的实例,必须做:

在下面这行代码中,我们可以看到使用malloc( )为对象分配内存:

第12章动态对象创建235下载obj* Obj = (obj*)malloc(sizeof(obj)) ;这里用户必须决定对象的长度(这也是程序出错原因之一)。因为它是一块内存而不是一个对象,所以malloc( )返回一个v oid*。C ++不允许将一个void* 赋予任何指针,所以必须映射。因为malloc( )可能找不到可分配的内存(在这种情况下它返回0),所以必须检查返回的指针以确信内存分配成功。但最坏的是:Obj->initialize( ) ;用户在使用对象之前必须记住对它初始化。注意构造函数没有被使用,因为构造函数不能被显式地调用—而是当对象创建时由编译器调用。这里的问题是现在用户可能在使用对象时忘记执行初始化,因此这也是引入程序缺陷的主要来源。许多程序设计者发现C的动态内存分配函数太复杂,令人混淆。所以,C程序设计者常常在静态内存区域使用虚拟内存机制分配很大的变量数组以避免使用动态内存分配。因为C ++能让一般的程序员安全使用库函数而不费力,所以应当避免使用C的动态内存方法。

12.1.2 运算符newC ++中的解决方案是把创建一个对象所需的所有动作都结合在一个称为n ew的运算符里。当用n ew(n ew的表达式)创建一个对象时,它就在堆里为对象分配内存并为这块内存调用构造函数。因此,如果我们写出下面的表达式foo *fp = new foo(1,2) ; 在运行时等价于调用m alloc(sizeof(foo)),并使用(1,2)作为参数表来为f oo调用构造函数,返回值作为t his指针的结果地址。在该指针被赋给f p之前,它是不定的、未初始化的对象—在这之前我们甚至不能触及它。它自动地被赋予正确的f oo类型,所以不必进行映射。缺省的n ew还检查以确信在传递地址给构造函数之前内存分配是成功的,所以我们不必显式地确定调用是否成功。在本章后面,我们将会发现,如果没有可供分配的内存会发生什么事情。我们可以为类使用任何可用的构造函数而写一个n ew表达式。如果构造函数没有参数,可以写没有构造函数参数表的n ew表达式:foo *fp = new foo ;我们已经注意到了,在堆里创建对象的过程变得简单了—只是一个简单的表达式,它带有内置的长度计算、类型转换和安全检查。这样在堆里创建一个对象和在栈里创建一个对象一样容易。

12.1.3 运算符deleten ew表达式的反面是d elete表达式。d elete表达式首先调用析构函数,然后释放内存(经常是调用free( ))。正如n ew表达式返回一个指向对象的指针一样,d elete表达式需要一个对象的地址。delete fp ;上面的表达式清除了早先创建的动态分配的对象f oo。d elete只用于删除由n ew创建的对象。如果用malloc( )(或calloc( )或realloc( ))创建一个对象,然后用d elete删除它,这个行为是未定义的。因为大多数缺省的n ew和d elete实现机制都使

236C ++编程思想下载用了malloc( )和free( ),所以我们很可能会没有调用析构函数就释放了内存。如果正在删除的对象指针是0,将不发生任何事情。为此,建议在删除指针后立即把指针赋值为0以免对它删除两次。对一个对象删除两次一定不是一件好事,这会引起问题。

12.1.4 一个简单的例子这个例子显示了初始化发生的情况:

我们通过打印t ree的值以证明构造函数被调用了。这里是通过重载运算符< 一起使用来实现这个运算的。注意,虽然这个函数被声明为一个友元(f riend)函数,但它还是被定义为一个内联函数。这仅仅是为了方便—定义一个友元函数为内联函数不会改变友元状态而且它仍是全局函数而不是一个类的成员函数。同时也要注意返回值是整个输出表达式的结果,它本身是一个o stream&(为了满足函数返回值类型,它必须是o stream&)。

12.1.5 内存管理的开销当我们在堆里动态创建对象时,对象的大小和它们的生存期被正确地内置在生成的代码里,这是因为编译器知道确切的数量和范围。在堆里创建对象还包括另外的时间和空间的开销。这儿提供了一个典型的方案。(我们可以用calloc( )或realloc( )代替malloc( ))1) 调用malloc( ),这个函数从堆里申请一块内存。2) 从堆里搜索一块足够满足请求的内存。可以通过检查显示内存使用情况的某种图或目录来实现搜索。这个过程很快但可能要试探几次,所以它可能是不确定的—即不必指望m alloc()花费完全相同的时间。3) 在指向这块内存的指针返回之前,这块内存大小和地址必须记录下来,这样以后调用malloc( )时就不会再使用它了,而且当我们调用free( )时,系统就会知道需要释放多大的内存。

第12章动态对象创建237下载实现这些运算的方法可能变化很大。例如,没有办法阻止在处理器里执行原始的内存分配。如果好奇的话,你可以写一个测试程序来猜测malloc( )实现的方法;也可以读一读库函数的源代码(如果有的话)。

12.2 重新设计前面的例子现在已经介绍了n ew和d elete(以及其他许多主题)。对于本书前面的s tash和s tack例子,我们可以使用到目前为止讨论的所有的技术来重写。检查这个新代码将有助于对这些主题的复习。

12.2.1 仅从堆中创建string类此处,类s tash和s tack自己都将不“拥有”它们指向的对象。即当s tash或s tack出了范围,它也不会为它指向的对象调用d elete。试图使它们成为普通的类是不可能的,原因是它们是v oid指针。如果d elete一个v oid指针,唯一发生的事是释放了内存,这是因为既没有类型信息也没有办法使得编译器知道要调用哪个析构函数。当一个指针从s tash或s tack对象返回时,在使用它之前必须将它做类型映射。这个问题将在1 3章和1 5章讨论。因为包容器自己不拥有指针,所以用户必须对它负责。这意味着在一个包容器上增加一个指向在栈上创建的对象的指针或增加一个指向在同一个包容器堆上创建的对象的指针时将会发生严重的问题。因为d elete表达式对于不在堆上分配的指针是不安全的。(从包容器取回一个指针时,如何知道它的对象已经在哪儿分配了内存呢?)为了在如下一个简单的S tring类的版本中解决这个问题,下面采取了一些步骤以防止在堆以外的地方创建S tring:

238C ++编程思想下载

相关文档
最新文档