1 / 20

实验二 模板的运用

实验二 模板的运用. 第二章预备内容的验证 完成时间: 9 月 16 日 ——9 月 19 日 提交实验报告,文件名为学号与姓名. 一、动态内存分配程序设计. 数组的定义: int a[10]; 只能说明 长度不变 的数组,而在实际应用中,我们希望数组的长度可以随时改变,或者由用户设定,这个要求可以通过“动态内存分配”技术实现。 动态内存分配:在程序运行过程中,根据需要在内存中进行内存分配,称为动态内存分配。. 动态内存分配程序设计. 程序使用的内存空间示意图: 栈区 堆区 全局数据区 程序代码区. 栈区 函数形参、局部变量 在程序 编译 时分配. 堆区

velika
Download Presentation

实验二 模板的运用

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 实验二 模板的运用 • 第二章预备内容的验证 • 完成时间:9月16日——9月19日 • 提交实验报告,文件名为学号与姓名

  2. 一、动态内存分配程序设计 • 数组的定义:int a[10];只能说明长度不变的数组,而在实际应用中,我们希望数组的长度可以随时改变,或者由用户设定,这个要求可以通过“动态内存分配”技术实现。 • 动态内存分配:在程序运行过程中,根据需要在内存中进行内存分配,称为动态内存分配。

  3. 动态内存分配程序设计 • 程序使用的内存空间示意图: • 栈区 • 堆区 • 全局数据区 • 程序代码区 栈区 函数形参、局部变量 在程序编译时分配 堆区 在程序运行过程中 分配的存储 全局数据区 程序代码区

  4. 动态内存分配程序设计 C++堆内存分配:运算符 new 和 delete 1.new: • 申请一个整型的空间: int *ip; ip=new int; *ip=10; • 申请一个整型空间并同时初始化: ip=new int (5); cout<<*ip<<endl; • 申请长度为10 的一维数组(数组的长度是可变的) int *ap; ap=new int[10];//注意:不能对动态数组初始化 for (int k=0;k<10;k++) cin>>ap[k]; 从堆中分配一个整型存储空间,返回指向内存的指针。 从堆中分配一个整型存储空间并初始化为5 从堆中分配连续10个整型存储空间

  5. 动态内存分配程序设计 2.Delete:把申请的堆内存空间还给系统: int *ip; ip=new int; *ip=10; delete ip; //表示归还一个整型的存储空间 int *ap; ap=new int[10]; for (int k=0;k<10;k++) cin>>ap[k]; delete[ ]ap; //表示归还一组整型的空间

  6. 动态内存分配程序设计 例1:运用动态内存分配申请一个数组,长度从外部输入: int n,*ip,*tp; cin>>n; ip=new int[n]; for (int k=0;k<n;k++) cin>>ip[k];//下标法 //指针法:ip固定 for (k=0;k<n;k++) *(ip+k)=2*(ip+k); //指针法:tp可变 for (tp=ip;tp<ip+n;tp++) *tp=2*tp; delete []ip; 思考题:这样的语句有什么问题? for (;ip<ip+n;ip++) *ip=2*ip;

  7. 动态内存分配程序设计 例2:程序可接收一个不定长的字符串: void main(){ char *cp; int len; cout<<“请输入字符串的长度:”;cin>>len; cp=new char[len+1]; cin>>cp; cout<<cp<<endl; delete []cp; }

  8. 动态内存分配程序设计 例3:程序可接收一个不定长的字符串(带输入容错) “容错”就是当用户输入不正确时,程序能对错误进行处理,确保程序不会产生严重后果。 void main(){ char *cp; int len, count=3; //最多可允许三次输入错误 do { cout<<“请输入字符串的长度(>0):”;cin>>len; } while (count-->0&&len>0); if (count==0) exit(0); //中止程序运行 cp=new char[len+1]; cin>>cp; cout<<cp<<endl; delete []cp; }

  9. 动态内存分配程序设计 • 实验任务1:编程实现可变长度的数组,并按要求设置断点,理解指针的运用。 #include <iostream.h> void main() { int n,*ip,*tp; cin>>n; //输入所需数组的长度 ip=new int[n]; //此处设置断点观察ip的值, ip有什么意义? for (int k=0;k<n;k++) cin>>ip[k]; //在此处设置断点观察ip, k的变化 for (tp=ip;tp<ip+n;tp++) cout<<*tp<<‘ ‘; //设置断点观察tp变化 delete []ip; } //在此处设置断点,观察ip的值,说明什么?

  10. 二、模板的运用 • 重用:重复使用某些部件 • 重用可在多个级别上进行,形式多样。 • 函数调用:多次使用的程序段单独写为函数,通过调用实现代码重用 • 类的合成(组合) : 在类的数据成员中使用另一个类的对象, 运用另一个类的功能. • 类的继承: 派生类包含基类, 把基类的函数作为派生类函数的一部分. • 模板技术: 模板类; 模板函数 ∨ ∨ ∨

  11. 含整数类型的类: class intClass{ int datax,datay; public: //构造 intClass(const int &parax,const int &paray) :datax(parax),datay(paray){ } //接口 int Getx(){ return datax; }//读出 int Gety(){ return datay; } void Setx(const int &p){ datax=p; }//设置 void Sety(const int &p){ datay=p; } };

  12. 含实数类型的类: class floatClass{ float datax,datay; public: floatClass(const float &parax,const float &paray) :datax(parax),datay(paray){ }//构造 float Getx(){ return datax; }//读出 float Gety(){ return datay; } void Setx(const float &p){ datax=p; }//设置 void Sety(const float &p){ datay=p; } };

  13. int float int float int float float int float int int float int float 建立一个模板类,所用类型以参数代替使用时:从一个模板生成含有特定类型的类 class MyClass{ Type datax,datay; public: MyClass(const Type &parax,const Type &paray) :datax(parax),datay(paray){} Type Getx(){ return datax; } Type Gety(){ return datay; } void Setx(const Type &p){ datax=p; } void Sety(const Type &p){ datay=p; } };

  14. template <class Type> • 语法要求: • 类定义开始前的模板、类型参数表 • Template <class T> • 类定义内部可用T表示类型 • 模板类型的使用:整体类型名包括 • MyClass<T> • 实例化时(定义对象),用一个已知的类型代替T class MyClass{ Type datax,datay; public: MyClass(const Type &parax,const Type &paray) :datax(parax),datay(paray){} MyClass(const MyClass<Type> &p) :datax(p),datay(p){} Type Getx(){ return datax; } Type Gety(){ return datay; } void Setx(const Type &p){ datax=p; } void Sety(const Type &p){ datay=p; } };

  15. C++的模板机制 • 把类定义或函数定义内使用的类型参数化,这些类型参数暂时作为占位符。 • 在用户使用这些类或函数时,参数化的类型会被绑定在实际类型上,这些实际类型可以是C++定义的类型,也可以是用户自定义类型。 • C++的类模板机制为 “泛型”设计提供了可能。 • 泛型:可操作于各种数据类型上的程序设计。(类型的抽象)

  16. 实例类的类型名: MyClass<float> 实例类的类型名: MyClass<int> int float int float int float float int int float float int float int int float • 模板关键字:Template • 类型形参用<>括起 • Class表明Type解释为类型名 template <class Type> class MyClass{ Type datax,datay; int flag; public: MyClass(const Type &parax,const Type &paray) :datax(parax),datay(paray){} MyClass(const MyClass<Type> &p) :datax(p),datay(p){} Type Getx(){ return datax; } Type Gety(){ return datay; } void Setx(const Type &p){ datax=p; } void Sety(const Type &p){ datay=p; } }; 不需要替换的类型 类型参数在MyClass使用时被具体类型替换。 使用MyClass: MyClass<float> obj_i(1.5, 2.6); 使用MyClass: MyClass<int> obj_i(10,20);

  17. 定义数组类模板 • 提取不同类型的数组类定义时共性的代码 • class Array{ //模板类型名与类型参数无关 • T *p; • unsigned len; • public : • Array(unsigned size){ • p=new T[len=size]; • assert(p!=NULL); //判断指针是否有效 • for (unsigned k=0;k<len;k++) p[k]=50; • } • }; template <class T>//增加类型参数 • 考虑字符型数组类的规格: • class charArray{ • char *ip; • unsigned ilen; • public : • chartArray(char *p, unsigned size){ • ip=new char[size]; • assert(p!=NULL); • for (k=0;k<size;k++) ip[k]=p[k]; • } • 考虑实型数组类的规格: • class floatArray{ • float *fp; • unsigned ilen; • public : • floattArray(float *p, unsigned size){ • ip=new float[size]; • assert(p!=NULL); • for (k=0;k<size;k++) ip[k]=p[k]; • } • 提出需求 • 考虑整型数组类的规格: class intArray{ int *ip; unsigned ilen; public : intArray(int *p, unsigned size){ ip=new int[size]; assert(p!=NULL); for (k=0;k<size;k++) ip[k]=p[k]; }

  18. 使用: 实例类型要有显式具体类型说明:<int>,<float>,<char> void main(){ Array<int> arr_i(5); Array<float> arr_f(5); Array<char> arr_c(5); for (int k=0;k<5;k++) cout<<arr_i[k];cout<<endl; for (k=0;k<5;k++) cout<<arr_f[k]; cout<<endl; for (k=0;k<5;k++) cout<<arr_c[k]; cout<<endl; }

  19. 实例化char类型 实例化int类型 实例化float类型 函数模板:求最大值的函数模板 template <class T> T max(T a, T b) { if (a>b) return a; //假设类型T的关系运算已定义 else return b; } void main() { int a=10, b=20; float x=2.5, y=5.4; char ch1=‘f’, ch2=‘g’; cout<<max(a,b)<<endl; cout<<max(x,y)<<endl; cout<<max(ch1,ch2)<<endl; }

  20. 编译处理注意的问题: • 模板类的说明与成员函数的定义要放在一个.h头文件中,应用程序必须用包含#include形式把模块类的完整定义包含进来 • 原因:模板类实例化时编译器必须看到模板类中成员函数的定义形式,以便确定有关操作的可行性、进行类型操作的检查。

More Related