类和动态内存分配.ppt_第1页
类和动态内存分配.ppt_第2页
类和动态内存分配.ppt_第3页
类和动态内存分配.ppt_第4页
类和动态内存分配.ppt_第5页
已阅读5页,还剩56页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第7章 类和动态内存分配 提要 本章介绍对类使用动态分配技术,以及由 此引起的问题的处理。 动态内存的使用将影响构造函数,析构函 数的设计和操作符的重载 7.1 动态内存和类 一个使用动态内存的例子 class StringBad private: char * str; / pointer to string int len; / length of string static int num_strings; / number of objects public: StringBad(const char * s); / constructor StringBad(); / default constructor StringBad(); / destructor / friend function friend std:ostream is.get(temp, String:CINLIM); if (is) st = temp; while (is return is; 小结:构造函数中使用new 构造函数中使用new初始化指针成员,则析 构函数重要使用delete; new和delete须兼容; 如果有多个构造函数,必须以同样方式使用 new,也可以将指针成员初始化为0; 应定义拷贝构造函数,实现深拷贝,其中还 要注意更新受影响的静态成员; 应定义赋值操作符,实现深拷贝。 有关函数返回对象的总结 返回指向const对象的引用 对象引用作函数参数是为提高效率,不用复 制对象,const表示不可改动实参 如果函数要返回传递给它的对象,也可以通 过传引用提高效率。 const Vector 此例中可以返回对象,但要调用拷贝构造函数 ,降低效率。const 与参数对应。 返回指向非const对象的引用 常用于重载赋值操作符和与流对象一起用的 操作符。 ostream int slag; ; char buffer150; char buffer2500; int main() chaff *p1, *p2; int *p3, *p4; p1=new chaff; p3=new int 20; p2=new (buffer1) chaff; p4=new (buffer2) int20; 看一个例子。从中可以知道 pd2通过布局new放在了buffer中,而pd1被放 在很远的堆中 第二个常规new查找一个新的内存块,而第二 个布局new分配的位置与第一次一样。说明布 局new使用传递给它的地址,它不跟踪内存单 元已被使用。 操作符delete 只能用于释放常规操作符new 分配的堆内存,本例中的buffer是静态内存, 不能使用delete来释放。 布局new用于对象 看一个使用布局new创建对象的例子( placenew1.cpp) 程序存在两个问题: pc1和pc3均由布局new创建,后者创建时会 覆盖前者的内存。如果对象中的成员是由new 来动态分配的,会引发问题(布局new使用指 定位置,而创建成员的new要查找空闲位置) 。 将delete用于pc2和pc4时会自动调用它们指 向的对象的析构函数;delete用于buffer时释 放常规new创建的整个内存块,不会调用在其 中创建的对象(由布局new创建)的析构函数 。 解决第一个问题的方法是程序员来控制为 布局new提供不同的地址,例如 pc1 = new (buffer) JustTesting; pc3 = new (buffer + sizeof (JustTesting) JustTesting(“Better Idea“, 6); 解决第二个问题的方法是显式地调用由布 局new创建对象的析构函数 pc3-JustTesting(); / destroy object pointed /to by pc3 pc1-JustTesting(); / destroy object pointed /to by pc1 需要注意,以创建对象相反的顺序删除之, 并且删除完对象之后再释放所在的缓冲区。 7.2 队列模拟 问题:一家银行想在一家超市中建立ATM 机,超市担心排队会影响其经营。编程模 拟ATM对超市造成的影响。 使用队列描述排队顾客:队列中的项为顾 客。假设,1/3的顾客1分钟接受服务, 1/3为2分钟,另外1/3为3分钟;顾客的到 达时间随机,但每小时到达的顾客数恒定 。 设计队列类,应有如下特征: 存储有序项序列 容纳的项目数有一定限制 能够创建空队列 能够判断队列为空或为满 可以从队尾添加项 可以从队首删除项 能够确定队列中的项目数 队列类的接口: class Queue enum Q_SIZE = 10; public: Queue(int qs = Q_SIZE); / create queue with a qs limit Queue(); bool isempty() const; bool isfull() const; int queuecount() const; bool enqueue(const Item / add item to end bool dequeue(Item / remove item from front ; 队列数据的表示 使用链表表示。链表由节点构成,每个节点 中保存相应信息以及指向下一个节点的指针 ,队尾的指针通常指向NULL。 struct Node Item item; struct Node * next; ; 此外还要有链表的起始位置,末尾位置,可 存储的最大项数以及当前存储的项数。可以 如下设计队列类的数据成员: class Queue private: / class scope definitions / Node is a nested structure definition local to this class struct Node Item item; struct Node * next; enum Q_SIZE = 10; / private class members Node * front; / pointer to front of Queue Node * rear; / pointer to rear of Queue int items; / current number of items in Queue const int qsize; / maximum number of items in Queue 队列最初是空的,所以 Queue:Queue(int qs) : qsize(qs) front = rear = NULL; items = 0; 注意:非静态常量数据成员和引用数据成员 不能赋值,但又不能在类定义中初始化。只 能使用成员初始化列表方式初始化 归纳:static, const成员的初始化问题 static const成员是类中的常数,在类定义 中初始化即可: class Test static const int size = 10; ; static 成员在类中声明,其初始化要放在 类定以外,通常是在实现文件中,例如 class Test static int size ; ; /实现文件 int Test:size = 10; /成员定义 const成员,在类定义中声明,在构造函 数的成员初始化列表中初始化,如前面的 例子。 判断队列为空、为满和确定队列中项目个数的成员函数 如下: bool Queue:isempty() const return items = 0; bool Queue:isfull() const return items = qsize; int Queue:queuecount() const return items; bool Queue:enqueue(const Item /如果为满,不许加入 Node * add = new Node; / create node if (add = NULL) return false; /节点没有创建成功 add-item = item; / set node pointers add-next = NULL; items+; if (front = NULL) / if queue is empty, front = add; / place item at front else rear-next = add; / else place at rear rear = add; / have rear point to new node return true; bool Queue:dequeue(Item item = front-item; / set item to first item in /queue items-; Node * temp = front; / save location of first /item front = front-next; / reset front to next item delete temp; / delete former first item if (items = 0) rear = NULL; return true; 队列中的节点是用new添加的,因此,在析构函 数中要用delete释放节点占用的空间: Queue:Queue() Node * temp; while (front != NULL) / while queue is not yet empty temp = front; / save address of front item front = front-next; / reset pointer to next item delete temp; / delete former front 客户类 class Customer private: long arrive; / arrival time for customer int processtime; / processing time for customer public: Customer() arrive = processtime = 0; void set(long when); long when() const return arrive; int ptime() const return processtime; ; void Customer:set(long when) processtime = std:rand() % 3 + 1; arrive = when; 模拟 输入:队列最大长度,模拟时间,每小时客 户数 程序使用循环,每次循环代表一分钟,其间 完成如下步骤: 判断是否有新客户,决定将其

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论