1 / 116

程序设计实习 第二十二讲 学期小结

程序设计实习 第二十二讲 学期小结. 期末考试. A 卷 形式与往年类似 内容以类和对象之后的内容为主 , 前面主要要求枚举和递归的算法思想和链表 B 卷 本学期全部作业题 , 即课程主页上每讲布置的作业. 内容提要. 枚举、递归、链表 C++ 语言综述 类的定义和使用 运算符重载 类的继承 虚函数和多态 输入输出流和文件处理 string 类和字符串处理 类模板和函数模板 STL 标准模板库. 枚举和递归. 两种解题的算法思想 枚举的思想 在解空间枚举所有可能性,逐一判断是否为可行解; 递归的思想

barton
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. 程序设计实习第二十二讲 学期小结

  2. 期末考试 • A卷 • 形式与往年类似 • 内容以类和对象之后的内容为主, 前面主要要求枚举和递归的算法思想和链表 • B卷 • 本学期全部作业题,即课程主页上每讲布置的作业 2

  3. 内容提要 • 枚举、递归、链表 • C++语言综述 • 类的定义和使用 • 运算符重载 • 类的继承 • 虚函数和多态 • 输入输出流和文件处理 • string类和字符串处理 • 类模板和函数模板 • STL标准模板库 3

  4. 枚举和递归 • 两种解题的算法思想 • 枚举的思想 • 在解空间枚举所有可能性,逐一判断是否为可行解; • 递归的思想 • 将待求解问题的解看作输入变量x的函数f(x),通过寻找函数g,使得f(x) = g(f(x-1)),并且已知f(0)的值,就可以通过f(0)和g求出f(x)的值. • 这样一个思想也可以推广到多个输入变量x,y,z等,x-1也可以推广到 x - x1,只要递归朝着出口的方向走就可以了. 4

  5. 链表 • 链表的结构 • 节点由“数据+指针”构成, 所有节点结构相同, 由指针连接在一起 • 链表的特点 • 顺序访问 • 任意位置插入和删除 • 链表的操作:插入、删除算法 • 插入和删除通过改变指针内容完成 • 删除操作对第一个节点和其它节点不同, 所以引入空的头节点, 简化删除操作. • 链表的分类 • 单链表 • 双链表 • 循环链表 5

  6. 内容提要 • 枚举、递归、链表 • C++语言综述 • 类的定义和使用 • 类的继承 • 虚函数和多态 • 运算符重载 • 输入输出流和文件处理 • string类和字符串处理 • 类模板和函数模板 • STL标准模板库 6

  7. C++语言综述 • 基本数据及其上的操作(相同类型数据间的操作) • char x,y; +, -, *, /, =; • int x,y; +, - , *, /, %, =, ++, --; • long x,y; +, -, *, /, %, =, ++, --; • __int64 x,y; +, -, *, /, %, =, ++, --; • float x,y; +, -, * , /, =; • double x,y; +, -, *, /, =; 7

  8. C++语言综述 • 用强制类型转换实现不同数据类型变量之间的运算; 例: float x = 3 + 2.5; • 用函数定义不同数据类型之间、不同操作数数目的复杂运算;例:double multiple(int, float, double); • 如果把操作符看作特殊的函数,并将其前置: +(int, int), *(float,float), ++(long) … 则得到一种统一的操作表示: 操作名(操作数1,… ) 8

  9. C++语言综述 • 为了扩展语言的能力,C++提供了类定义的语法机制,可以组合基本的数据类型定义更复杂的数据类型及其上的操作: • 例: class A { public: int x; float y; A & operator+(const A& a1); …… } 9

  10. C++语言综述 • 在定义新的类时可以使用已经定义好的类,并将其看作基本类型来使用,如此的嵌套结构可以定义出任意复杂的类; • 可以用友元函数实现不同类对象之间的操作, • 如此便完成了任意复杂的数据及其上的任意复杂的操作。 10

  11. C++语言综述 • 语言提供的功能并没有到这里就停止: • 与用户交换数据 • C++输入输出流 • 处理数据管理的问题 • C++文件流处理 • 处理异常错误 • C++异常处理 11

  12. C++语言 • 关于代码重用问题 • 类的派生 • 抽象类/虚函数/多态 • 类模板和模板类 • 函数模板和模板函数 • C++类库 12

  13. 内容提要 • 枚举、递归、链表 • C++语言综述 • 类的定义和使用 • 运算符重载 • 类的继承 • 虚函数和多态 • 输入输出流和文件处理 • string类和字符串处理 • 类模板和函数模板 • STL标准模板库 13

  14. 类的定义和使用 • 定义类的目的 • 类的定义方法 • 类中的主要概念: • 成员变量、成员函数、public、protected、private • 类中的特殊函数:构造函数和析构函数 • 类中的特殊种类成员:引用、对象、常量、静态 • 类的友元 • 用类定义对象:一般对象、常量对象和常量成员函数 • this 指针 14

  15. 类的定义和使用 • 定义类的目的 • 定义出一种比较复杂的数据类型来与客观世界中的复杂对象相对应; • 通过类的成员函数定义这种复杂对象上的操作; • 如此便可以把一个复杂对象当作一个整体来处理,是实现抽象,减低问题复杂度的一种方法。 15

  16. 类的定义和使用 • 类的定义方法 – 类定义 // man.h class Man { private: int nAge; char szName [20]; public: int GetAge () ; //方法, Method, 也叫成员函数 void SetName( char * szName); //成员函数 }; 16

  17. 类的定义和使用 • 类的定义方法 – 定义成员函数 //Man.cpp: #include “man.h” int Man::GetAge(){ return nAge; } void Man::SetName ( char * name) { strcpy( szName,name); } 17

  18. 类的定义和使用 • 类中的主要概念: • 成员变量:类中定义的变量 • 成员函数:类中定义的函数 • 访问限定符 • public : 可以在任何地方访问 • protected :在自己内部和子类内部访问 • private : 仅在类定义内访问 18

  19. 类的定义和使用 • 类中的特殊函数 • 构造函数 • 析构函数 • 各种构造函数和析构函数的调用时机 19

  20. 构造函数(定义) • 构造函数是 public 的; • 无返回值,可以有0到多个参数; • 用户不定义,自动生成缺省的; • 缺省的构造函数什么也不做,没有参数; • 用户定义,则没有缺省的; • 可以定义多个构造函数; • 用于初始化对象的变量; 20

  21. 构造函数(调用方式) • 定义对象变量时: Complex c1,c2(2),c3(3,5); • 创建新变量对象时: Complex * pc1 = new Complex ; Complex * pc2 = new Complex(3,4); • 创建数组对象时: Test array1[3] = { 1, Test(1,2) }; Test * pArray[3] = { new Test( 4), new Test(1,2) }; 21

  22. 构造函数(复制构造函数) • 特殊构造函数,只有一个参数,类型为本类的引用; • 如果没有定义,生成缺省的复制构造函数; • 如果定义,没有缺省复制构造函数; • 与前面说的构造函数无关; Complex c2(c1); Complex c2 = c1; • 参数传递时,复制参数 • 函数返回时复制返回值 22

  23. 转换构造函数 • 带有一个参数的非复制构造函数的构造函数 例: class Complex { public: float real,imag; Complex( double f ) { real = f ; imag = 0; } Complex( int i = 0 ) { real = i; imag = 0; } ~Complex() { printf( "Destructor called\n"); } }; 23

  24. 析造函数(定义) • 只有一个; • 没有参数和返回值; • 如果不定义,自动生成,什么也不做; • 如果定义,没有缺省的; • 完成对象消亡前的收尾工作; • ~类名(){ … } 24

  25. 析造函数(调用时机) • 变量消亡 • 出作用域 • Delete • 函数返回值用后; 25

  26. 各种构造函数和析构函数的调用时机 • 构造函数 • 全局变量: 程序运行前; • main中变量: main开始前; • 函数中静态变量: 函数开始前; • 函数参数:函数开始前; • 函数中变量:函数开始前; • 函数返回值:函数返回前; 26

  27. 各种构造函数和析构函数的调用时机 • 析构函数 • 全局变量: 程序结束前; • main中变量: main结束前; • 函数中静态变量: 程序结束前; • 函数参数:函数结束前; • 函数中变量:函数结束前; • 函数返回值:函数返回值被使用后; 27

  28. 类的定义和使用 • 类中的特殊种类成员 • const和引用成员 • 对象 • 静态 28

  29. 类的定义和使用 • 类中的特殊种类成员 • const和引用成员 • 初始化const 成员和引用成员时,必须在成员初始化列表中进行。 class example { private : const int num; int & ret; int value; public: example( int n,int f) : num(n), ret(f), value(4) { } }; 29

  30. 类的定义和使用 • 类中的特殊种类成员 • 对象 例: class Big { private: int n; base1 b1; base2 b2,b3; public: Big (int n ) : b2(n),b3(2) { } }; 30

  31. 类的定义和使用 • 类中的特殊种类成员 • 对象 • 有成员是其他类的对象时,本类称为封闭类 • 封闭类对象生成时,先执行所有对象成员的构造函数,然后才执行封闭类的构造函数。 • 对象成员的构造函数调用次序和对象成员在类中的说明次序一致,与它们在成员初始化列表中出现的次序无关。 • 当封闭类的对象消亡时,先执行封闭类的析构函数,然后再执行成员对象的析构函数。次序和构造函数的调用次序相反。 31

  32. 类的定义和使用 • 类中的特殊种类成员 • 静态成员 属于整个类而不属于任何类的对象的变量可以定义成静态成员。 例如: class Apple { private : int nWeight; static int nTotalWeight; static int nTotalNumber; public: Apple( int w) ; ~Apple( ) ; static void PrintTotal(); }; • 在静态成员函数中,不能访问非静态成员变量,也不能调用非静态成员函数。 32

  33. 类的定义和使用 • 类的友元 • 若想要其它类或函数访问本类的私有成员,可以将其它类或函数说明为自己的友元,此举有利于定义不同类对象间的操作。 例如: class Thing { private: int data; public : friend void SetData( Thing & t, int nValue); friend void B::function(); friend class other; }; 33

  34. 类的定义和使用 • 用类定义对象: • 一般对象 • 常量对象和常量成员函数 一般对象,例如: class A{ …… } A a1,a2; 34

  35. 类的定义和使用 • 用类定义对象: • 常量对象和常量成员函数 • 如果不希望对象的值被改变,可以将对象定义为常量,例如: const A a1; // a1的值不能改变 通过a1只能访问一类const成员函数,形如: class Sample { private : int value; public: void SetValue() const; //函数中不能改变成员的值 } 35

  36. 类的定义和使用 • this 指针 • 在定义某个类的代码中,可以用this指针指代正在定义的类的对象。例如: class Complex { float real,imag; public: Complex * ReturnAddress ( ) { return this; }// c.ReturnAddress 等效于 & c float ReturnReal() { return this -> real;//等效于return real; } Complex operator += ( Complex & c) { real += c.real; imag += c.imag; return * this; }}; 36

  37. 内容提要 • 枚举、递归、链表 • C++语言综述 • 类的定义和使用 • 运算符重载 • 类的继承 • 虚函数和多态 • 输入输出流和文件处理 • string类和字符串处理 • 类模板和函数模板 • STL标准模板库 37

  38. 运算符重载 • 运算符重载的目的 • 可以对自定义的类的对象使用运算符构建表达式 • 可以重载的运算符 • +、-、*、/、%、^、&、~、!、|、=、<<、>>、!=、…… • 运算符重载的方法 • 说明为成员函数 • 说明为友元函数 38

  39. 运算符重载 • 说明为成员函数 -- 鼓励 class CSet { public: CStet(); // constructor const CSet &operator+( const CElement & ) const; …… }; • 说明为友元函数 -- 左操作数不是本类对象 class PhoneNumber { friend ostream &operator<<( ostream&, const PhoneNumber & ); friend istream &operator>>( istream&, PhoneNumber & ); … }; 39

  40. 运算符重载 • 流插入运算符的重载,参数和返回值要使用ostream & 类型 ostream & operator<<( ostream & o,const CStudent & s){ o << s.nAge ; return o; } 40

  41. 内容提要 • 枚举、递归、链表 • C++语言综述 • 类的定义和使用 • 运算符重载 • 类的继承 • 虚函数和多态 • 输入输出流和文件处理 • string类和字符串处理 • 类模板和函数模板 • STL标准模板库 41

  42. 类的继承/派生 • 继承的目的 • 继承的方式:public、protected、private • 派生类的构造函数 • 基类对象指针和派生类对象指针的转换 • 覆盖的概念 42

  43. 继承的目的 – 代码重用 • 已经有一个类A,现在要定义的类B和类A很相似,只是多了一些东西,或者说,B是一种特殊的A。 例如: class 学生{ class 学生干部:学生{ public: public: char name[10]; char title[20]; char id[10]; char level; void study(); void duty(); } } 43

  44. 类的继承/派生 • 继承的方式:public、protected、private • class derived: public base • public -> public • protected -> protected • private -> private • class derived: protected base • public、protected -> protected • class derived: private base • public、protected -> private 44

  45. 类的继承/派生 • 派生类的构造函数 FlyBug::FlyBug ( int legs,int color, int wings) :Bug( legs,color) { nWings = wings; } • 在创建派生类的对象时,需要调用基类的构造函数:初始化派生类对象中从基类继承的成员。在执行一个派生类的构造函数之前,总是先执行基类的构造函数 45

  46. 类的继承/派生 • 派生类的构造函数 • 调用基类构造函数的两种方式 • 显式方式:在派生类的构造函数中,为基类的构造函数提供参数 derived::derived(arg_derived-list):base(arg_base-list) • 隐式方式:在派生类的构造函数中,省略基类构造函数时,派生类的构造函数则自动调用基类的默认构造函数 • 派生类的析构函数被执行时,执行完派生类的析构函数后,自动调用基类的析构函数 46

  47. 类的继承/派生 • 基类对象指针和派生类对象指针的转换 • 基类指针可以指向子类对象,但用起来就象基类对象 • 将基类指针赋值给子类指针要显式类型转换 例如: class C:public P{…} P *p1 = 0, p( 30, 50 ); C *c1 = 0, c( 2.7, 120, 89 ); p1 = &c; // assign address of c to p1 c1 = static_cast< Circle * >( p1); 47

  48. 覆盖的概念 • 基类和子类中的同名函数,在子类中看不到基类的相应函数,这种现象称为覆盖。 48

  49. 内容提要 • 枚举、递归、链表 • C++语言综述 • 类的定义和使用 • 运算符重载 • 类的继承 • 虚函数和多态 • 输入输出流和文件处理 • string类和字符串处理 • 类模板和函数模板 • STL标准模板库 49

  50. 虚函数和多态 • 引入虚函数的目的 • 虚函数的定义 • 纯虚函数和抽象类 • 在构造函数和析构函数中调用虚函数 • 虚析构函数 50

More Related