C++语言基础 潘爱民 panaimin@icst.pku.edu.cn http://www.icst.pku.edu.cn/compcourse 内容简介 !C++语言基础 !Object-Based Programming !Object-Oriented Programming !STL C++之我见 !C++语言在变化,我们的概 念也要调整变化 !最能反映OO思想的语言,掌 握C++有助于理解OO !区分C和C++,C++不是C语 言,不要用看待C语言的方式 来看待C++ 掌握C++语言的基础知识 !操作系统的基础知识 –文件API、内存管理… infrastructures !计算机原理 –汇编语言 – C/C++是产生ASM代码的framework !编译和执行过程 –编译过程 –执行过程 !许多概念 –进程、heap、stack,... 程 序 开 发 过 程 开发 编辑 编译 出错? 链接 执行 结果正确? 结束 源程序 file.cpp 目 程序 file.obj 和 OBJ 执行程 序file.exe Yes Yes No No Build过程 compile time !Compile + link ! 待错 和 –错 要 , 错 – , 确 理解不 程 序 ! ?compile options和link options – IDE¢ ?? —— 要知£? –¥?行 ?? –程序代码¢ ?? 执行过程 runtime !Load、§ currency1、'“化、main ! 调? –?? – assertion !程序 fifl的 –? –系统fifl – CRT –内存?· /* STRCPY.C: This program uses strcpy * and strcat to build a phrase. */ #include <string.h> #include <stdio.h> void main( void ) { char string[80]; strcpy( string, "Hello world from " ); strcat( string, "strcpy " ); strcat( string, "and " ); strcat( string, "strcat!" ); printf( "String = %s\n", string ); } C语言 ? C语言?? !结?化 – 简?的方” ?? …‰的结? ! ?式 `、简′ – ??代码ˉ?、程序的 ˙? !?¨ ?接?汇编语言的 能??ˇ – — 于编 系统 件和 件 ?ˇ ` !调?方 ! ? !目 代码 、 ? C++语言内容 ! ? –内?(built-in)、 a 、 的 ! ?式 ! 语? ! (??) !o 理 ? ! ? – 10、012、0x12、1L、3.14、1.0E-3、 true、’a’、”file name is \”myproc.c\”” !变? – 不能用 ,?? ,有 – ? (first_filename)、? ?? (FirstFilename) – ? !基 ? – void、char 、 short 、 int 、 long 、float 、double 、signed 、unsigned ? ( ) !?ˇ –?向某 变?的地址 –注 未经'“化的?ˇ不能使用 ! 符串 – C 的 符串 ?向char的?ˇ –使用string、wstring !const修饰符 – ?修饰变?、?ˇ、 !引用? –语 别 ? ( 二) !结?struct !联 union !枚举enum ! bool? ! 组 – 维 组、多维 组 – 组和?ˇ之间的 系 – vector ! typedef ! volatile修饰符 ? !const ? const int size = 100; // 在size的有 范围内不 变 char *const aptr = mybuf; // ??ˇ *aptr = ‘a’; // ” aptr = yourbuf; // ” const char *bptr = mybuf; // ?向 ? *bptr = ‘a’; // ” bptr = yourbuf; // ” const char *const p = “abcde”; char *p = “abcd”; // ”,—— 外 const也 ?用在 的参 说 ¢ !const 员 在?的 ¢有 int GetData() const; // 不 改变 象的 组 ! 维 组 int number[100]; extern int number[]; !多维 组 int number[100][10]; extern int number[][10]; !结? 组 struct { float x, y; } complex[100]; 结?struct !简?结? struct date { int year, month, day; char mon[3]; }; !匿 结?和嵌套结? struct person{ char name[30]; char sex; int age; int weight; struct { int areacode; long number; }; } Jim; Jim.number = 1234567; 结?struct( ) !结?¢的currency1域 struct mybitfields { unsigned a : 4; unsigned b : 5; unsigned c : 7; } test; !访问结?¢的 员 .操作符 Jim.number = 1234567; 联 union !联 ? union u_tag { int ival; float fval; char *pval; }; MFC¢典 的 ?是VARIANT的 !联 ?结?的区别 内存分配、引用方式 枚 举 ? !枚举? enum Days // Days为枚举? { saturday, // 缺省saturday = 0 sunday = 0, // ? sunday = 0 monday, // monday = 1 tuesday, // tuesday = 2 wednesday, // 等 thursday, friday } today; // 变?today为? Days !使用 ? enum Days yesterday; // C和C++¢都 ” Days tomorrow; // C++ ”,C ” yesterday = monday; int i = tuesday; // ”; i = 2 yesterday = 0; // ”,不允许 yesterday = (Days)0; // ”,但结果不确 typedef ! ? typedef char FlagType; const FlagType x; typedef int (FAR WINAPI *FARPROC)(); typedef int (WINAPI *PROC)(); PROC proc ...... int retVal = (*proc)(); 变?的说 !无 联 、结? struct fruit { int type; char *name; union { DWORD color; struct { BYTE red; BYTE green; BYTE blue; }; }; }; ! enum、struct、union 说 变?时不需要使用这? // 已经 EnumDay、StructPoint、 UnionColor 说 enum EnumDay day; --------- day; EnumDay day; struct StructPoint point; --------- StructPoint point; union UnionColor color; --------- UnionColor color; ?ˇ ! ?ˇ是 变?, 包含另 变?的地 址,因此,通过?ˇ ?间接地访问另 变? int x, *px // ?ˇ px = &x; ! 运算符&和* &x 示取x的地址 *px 示取px所?的变? ! ?ˇ?整 的运算(p为?ˇ) p++ 示紧接*p之后的变?的地址 p-- 示紧靠*p之前的变?的地址 p + n 示紧接*p之后的 n 变?的地址 p - n 示紧靠*p之前的 n 变?的地址 p1 - p2 ?向同 组区的两?ˇ之间的变? *sizeof算符 ! ?ˇ嵌套 int **ppx 示?向int *的?ˇ ?ˇ ( ) !?ˇ?结? struct date *pd ...... 注 pd 要赋值 pd->day pd->month 相当于 (*pd).year 说 括号是必须的,因为. 优先级? !运算符&和* &x 示取x的地址 *px 示取px所?的变? ! .*和->* object.*pMember pobject->*pMember !?ˇ? 的转换 ?ˇ的转换有很?的随 ?,但 要保证安全? ?ˇ( 二) .*和->* Class A{ public: int m_n; char m_ch; }; int A::*pMember = &(A::m_n); A object; A* pobject = &object; object.*pMember = 1;// 际上是object.m_n = 1; pobject->*pMember = 2;// 际上是pobject->m_n = 'c'; ?ˇ ( 三) !?ˇ ? 1. int x, a[10], *pa; pa = &a[0]; x = *pa; 2. 若有??说 struct { int x, *y } *p 则 ++p->x; // x加 p->x++; // x加 (后加) (++p)->x; // p先加 ,再访问x *p->y++; // 先访问y的内容,再加 *(p->y)++; // 同上 *p++->y; // 先访问y的内容,后p加 *(p++)->y; // 先访问y的内容,后p加 3. ?ˇ void (PASCAL * pFunc)(int, int); 赋值 pFunc = GetProcAddress(hLib,”Func"); 调用 (*pFunc)(100, 100); 引用——reference !引用 – 他变?的别 – 要'“化 !引用??ˇ的区别 – ?ˇ 能未被'“化 !引用 ? – int &r = i; ?ˇ变?和引用 ! ?ˇ变? #include <stdio.h> void swap(int *a, int *b) { int tmp = *b; *b = *a; *a = tmp; return; } int main() { int i = 7, j = 3; swap(&i, &j); printf(“The Result is :i =%d, “ “ j = \n”, i, j); return 0; } !引用 #include <stdio.h> void swap(int &a, int &b) { int tmp = b; b = a; a = tmp; return; } int main() { int i = 7, j = 3; swap(i, j); printf(“The Result is :i =%d, “ “ j = \n”, i, j); return 0; } 变?? ! 动变?和外部变? 动变? ¢说 的变? ,在某 内部 auto int i; ?? 在 ¢,currency1于 ¢,有 在 ¢ 外部变? 所有 外部 的变? ,在 ¢说 extern int i; ?? 在 外,不在 ¢,全程有 ! 变?和 存 变? 变? 内部 变?和外部 变? static int i; ?? 变?的 ?,有 在 ¢ 分 有 和生存 存 变? register int i; register char x; ?? 能用于 动变?、 、? (int、char,?ˇ) 变?? ? #include <math.h> static int i; /* 外部 变? */ extern int Total; /* 外部变?, 在 文件¢*/ int Add(int x, int y) { int z; /* 动变? */ extern int Total; /* ?省 */ z = x + y; Total ++; return z; } int Sub(int x, int y) { int z; /* 动变? */ static int SubTime = 0; z = x - y; SubTime ++; return z; } #include <stdio.h> int Total = 0; /* 外部变?, */ int main() { register int i1, i2; /* 动变? */ int Result1, Result2; i1 = 10; i2 = 20; Result1 = Add(i1, i2); Result2 = Sub(i1, i2); printf(“i1 = %d , i2 = %d\n”, i1, i2); printf(“Result1 = %d , Result2 = %d\n”, Result1, Result2); printf(“Total = %d\n”,Total); return 0; } new和delete !分配内存 在C¢ char *name = (char *)malloc(Length + 1); 使用new char *name = new char[Length + 1]; ! 内存 在C¢ free(name); 使用delete delete [] name; ?式 !算 运算符 * / % + - ++ -- ! 系运算符 ! < <= > >= == != && || !赋值运算符 = ! 件运算符 ?: !sizeof运算符 sizeof ?式( ) !New、delete ! currency1运算、 反运算 currency1 & | ^ 、 ~( 反) ! currency1运算 >> << ! 号 !? 转换 式转换、 式转换 !… ?式 语? !if、return、 ?式、goto !for、continue、break、switch !while、do-while !try、… 语? ! 号 作分 符,也 作运算符 ! 操作语? 语? ? ! 件语? if ( 件 ?式) 语? if ( 件 ?式) 语?A else 语?B !… 语? 组语?用{ }括 来 if ( 件 ?式) { 语?a; 语?b; ....… } !简化 件 ?式 ?式1 ? ?式2 : ?式3 !开 语? switch ( ?式) { case ?式1: 语?1; break; case ?式2: 语?2; break; ....... default: 语? break; } 语? ?( ) ! while语? – while ( ?式) 语? ! for语? for( ?式1; ?式2; ?式3) 语? 赋'值 结束 件 变?行为 ! do-while语? do { 语?; } while ( ?式); ! break, continue语? ! 号用于 ?式、 操作语? ! 、 原 – ? 、 参 – 编译时 ,? – bool Func(int x, int y); ! ( ) !参 – pass-by-value – pass-by-reference – 缺省参 ?? !说 void func(int a, int b, int c=10); ! 调用 func(5,6); 相当于func(5,6,10); ( ) ! 值 –也 ? 引用 !引出 (MS) !inline – 说 加前¢inline, inline void func(int a, int b) { printf(“%\n a = %d, b = %d\n”, a, b); } !extern “C” ( 二) !¥?行参 int argc, char *argv[] !extern static !调用参 理 _stdcall _cdecl !参 不确 – int printf(char *, ...); ! ?ˇ – ?ˇ (*fp) – 取地址£?是 ?ˇ –调用 pf(); (*pf)(); ( 三) ! C++ a – ¥ #include <iostream> – using namespace std; ! C – stdio,stdlib.h,math等 – #include <cstdio> ! §? – void print(int i); void print(char *s); void print(int *p); ? void main() { /* Function prototypes */ long lift( int ), step( int ), drop( int ); void work( int number, long (*function)(int i)); int select, count; . . . select = 1; switch( select ) { case 1: work( count, lift ); break; case 2: work( count, step ); break; case 3: work( count, drop ); default: break; } } /* Function definition */ void work( int number, long (*function)(int i) ) { int i; long j; for ( i=j = 0; i < number; i++ ) j += ( *function )( i ); } 说 ( ) !说 1. 变?说 extern int global; extern int global = 10; // ? 2. 说 void Func(int x, int y); * 含说 *通 #include文件¢包含的是 的说 3. 结?、联 、枚举? 说 (?class) struct POINT { int x; int y; }; (definition) ! 1. 变? int global; 2. void Func(int x, int y) { ...... return; } 3. 结?、联 、枚举? (?class) struct POINT { int x; int y; }; struct POINT point; 注 C++允许变?在 的§ 地方 说 ,currency1'上,“?? 使用???? 作用域 (scope) !local scope { } !namespace scope namespace XXX { ... } !class scope !scope operator (::) !using !using namespace std; §? !相同的 ,不同的参 ,编译 必须能?区别 !参 相同, 值不同, 不是§? !不能包含两 extern “C” §?? !§? ?ˇ ?? ! ? template <class Type> Type min(Type a, Type b) { return a<b?a:b; } min(10,20); min(10.0, 20.0); !?? 化 ——fi参 fl – 式 化 – 式 化 – min<int>(10,20); ??( ) !两 编译?式 – inclusion?式 – separation?式(export ) !???化 !§? ?? o 理(exception handling) !错 理机 、错 代码 – !Throw(raise) an exception – Throw expression –??于return 语? !Try、catch语?(handler) – try{} – catch(type){} catch(type obj){} !??于 调用 –但是? ?配发生在runtime o 理( ) !嵌套机 , 果最外· 有 理,则fi terminate来 理 !Local object正 ? !rethrow –在catch??¢£? ?throw !Catch all handler – catch(…) ! 时? 能的o – int func(int) throw(string); – 果 有? 的o 发生,调用unexpected() ? 理? 他 ! 式 换行 分 符的作用, 行用?\? !注 用/*开“,用*/结束 在C++¢,也 ?用// !? 符号 式 #define 符号 / 符串 #define TRUE 1 ”参 的? #define IS_LEAP_YEAR(y) y%4==0&&y%100!=0 ||y%400==0 注 ? 是代换,所?保?变?整 ?, 想象IS_LEAP_YEAR(x+1) #define IS_LEAP_YEAR(y) (y)%4==0&&(y)%100!=0||(y)%400==0 ? 理? 他( ) ! 件编译 用” #ifdef 识符 #ifndef 识符 #if 件 ?式 语?....... #else ( …) 语?....... #endif #ifdef DEBUG ˇ 调?的语?....... #endif #undef语? ! 编译?示 #pragma ! 符串转 \t \b \n \r \’ \” \a \\ \ooo \xhhh 等 Object-Based Programming !class ‰ ? ! 象 !? ? ? !访问 、 ` !嵌套? !?¢ 员'“化 !′? !?¢运算符§? !??? ?的 class ? 识符 { private : 员 和 员 说 // 在?的外部不能?接访问 protected : 员 和 员 说 // ?在ˉ生?¢被访问 public : 员 和 员 说 // ?在?外被访问 }; ?的 ? class CShape { protected: COLORREF color; public: CShape() { color = 0;} virtual ~CShape() {} virtual void Display() = 0; virtual void MoveTo(int x, int y) = 0; }; ? 和 ? !? ? 是?? 同 的操作,? ?有多 ? 当程序¢? ?的 象( )时,? 相˙的参 ,编译 调用—当的? 进行 象'“化 作¨ ? 有 值 ! ? ? 的 为~加? 当 象被使用 之后,˙?通过delete语?来 相˙的 内存,这时 ? 被调用, ?结束 理 作¨ 果 象为 动变?,在 ¢? 的,则当变?的生¥ ? 结束时,编译 动调用 ? ¨ ? !缺省? !Copy? ? ? ? 示 ?的 class CPoint : public CShape { private : POINT m_point; public: CPoint(); CPoint(const CPoint &); CPoint(int x, int y); ~CPoint(); void SetPoint(POINT ); void Display(); void MoveTo(int x, int y); }; 使用1 CPoint *point1 = new CPoint; …… delete point1; 使用2 CPoint *point2 = new CPoint(100, 100); …… delete point2; 使用3 { …... CPoint point1; CPoint point2(100,100); …… } // 动调用 ? ?的 ‰ CPoint::CPoint(int x, int y) { m_point.x = x; m_ point.y = y; } CPoint::~CPoint() { } void CPoint::SetPoint(POINT point) { m_point = point } void CPoint::Display() { ……. } void CPoint::MoveTo(int x, int y) { m_point.x = x; m_ point.y = y; } ?的 员 !所有?的 象?ˇ同 员, class CPoint { public: int x, y; static int nCount; … static int GetCount(); }; – int CPoint::nCount = 0; int CPoint::GetCount() { return nCount; } – 通过? 访问 CPoint::nCount ?向? 员的?ˇ ! class CShape { public: int x, y; int width, height; … int GetHeight(); }; int (*pf)(); // error! int (CShape::*pf)(); // ok! pf = CShape::GetHeight; (myShape.*pf)(); 运算符§? !运算符§?— C++语言的 ? – … ?§?加、 、 、 等运算 ! C++¢ ?§?的运算符 + - * / % ^ & | ~ ? , = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= && || ++ -- -> ->* [ ] ( ) new delete new[] delete[] ! 注 运算符的语 – ¥ operator= 引用? : return *this; 运算符§?示 ! 目运算符 说 CComplex operator+(CComplex complex) const; CComplex CComplex::operator+(CComplex complex) const { return CComplex(x + complex.x, y + complex.y); } 使用 Complex z1, z2, z3; …… // '“化 z1和z2 z3 = z1 + z2; !?目运算符 ? 转换运算符§? !Operator type() class CPoint{ operator char *(); }; 使用 式转换 用在 参 式转换 char *point = static_cast<char *>(myPoint) ??ˇ !?ˇp,?向 象 CComplex *p; 赋值 1. p = new CComplex(1, 1); 2. CComplex z1(10, 10); p = &z1; 使用 p->x p->y z1.x z1.y p->InitValue(); z1.InitValue(); this?ˇ !在?的内部?向? 的? ˇ !在 员 ¢,this? ˇ?¨ 使用上的方 !this?ˇ ?的多 象区分开来 ? 员的访问?? !三 ?? – private 在?的外部不能?接访问 – protected ?在ˉ生?¢被访问 – public ?在?外被访问 ! ` – `? – ` 嵌套? ! 说 class BufferIO { public : enum IOError { none, Access, General }; class BufferedInput { public: int read(); int good(); private: IOError inputerror; }; class BufferedOutput { …... }; }; ! ‰ int BufferIO::BufferedInput::read() { …... } 另 typedef BufferedIO::BufferedInput BIO_INPUT; int BIO_INPUT::read() { …… } // `? class MyClass { friend class MyOtherClass; // Declare a friend class private: int topSecret; }; class MyOtherClass { public: void change( MyClass myc ); }; void MyOtherClass::change( MyClass myc ) { myc.topSecret++; // ?访问MyClass的 有 } // ` class Complex { public: Complex( float re, float im ); friend Complex operator+( Complex first, Complex second ); private: float real, imag; }; Complex operator+( Complex first, Complex second ) { return Complex( first.real + second.real, first.imag + second.imag ); } ` ?? ! ?? ? ? 为?参 ?的 template < class T > Swap( T &a, T&b) { T temp; temp = a; a = b; b = temp; } ! ???(??? ?生 ) ? ? 为?参 ?的? template < class T > class Stack { private : T pool[maxNum]; int sp; public: Stack(); void Push(T x); T Pop(); BOOL IsEmpty() const; BOOL IsFull() const; }; 使用 Stack < int > intStack; Stack < float > float Stack; ??( ) ! ?? ! 化 !??参 ? 参 、 ? 参 !两 编译?式 – inclusion?式 – separation?式(export ) !????化(class template specializations) !???部分?化(class template partial specializations) 向过程转换 向 象 ! 向过程? 能为组 ?` 在C语言¢? 作为 能?` 通过 结?来 的问 在 能( )之间?参 的?式被 ¨ ! 向 象 用?class ? ??? 相 的操作 用?的a ?来 ‰?的§用? 多 ?¨ Object-Oriented Programming !CShape !CPoint !CLine !CCircle !CArc !CText CShape CPoint CLine CCircle CArc CText ?的a ,ˉ生? !ˉ生??? – a ?的 ?和操作 – 修改 ?的某?操作 – —加 的 ?和操作 – a ‰ C++语言的 §用? – ˉ生?不能访问 ?的 有 ?和操作 – 若 ?有多 ?,则 为多§a ? ?? ˉ生? !说 class derived_class_name : private parent_class_name { … }; class derived_class_name : public parent_class_name { … }; ˉ生?( ) class Private: public: int a; int method1(); parent char ch; ˉ生 class derived: Private: public: int a; int method1(); public parent char ch; int method2(); int new1; class derived2: Private: public: int a; int method1(); char ch; int method2(); public derived int new1; int method3(); int new2; ˉ生 ˉ生? ( 二) !ˉ生?的? // ?用 ?的? 进行'“化 derived::derived(int Init_a, char Init_ch, int Init_new1) : parent(Init_a, Init_ch) { new1 = Init_new1; } derived2::derived2(int Init_a, char Init_ch, int Init_new1, int Init_new2) : derived(Init_a, Init_ch, Init_new1) { new2 = Init_new2; } ! 先执行 ?? ,再执 行ˉ生?的? ,?序 – 1 基? – 2 内嵌 象 – ˉ生? ˉ生? ( 三) !′ ? – 果 ?要 为?·o¢的基?, ? 要 virtual – CShape *obj = new CRect(…); ... delete obj; – 果不 virtual,则memory leak ˉ生?( )——多§a Collectible CollectibleString a String a Collectible CollectibleSortable a Sortable a CollectibleSortableString a a ˉ生? ( ) !在多§a 结?¢,相同的基? 能 在 结?¢出‰多o – 在内存¢有多? – 果不 出‰这 ?,必须使用′ ?a !在多§a ??,基?¢ 能包含 相同的 , 果编译 不能区分 ?调用? 的 ,则必须用 号 分 符(::) 式? ? MyDerivedClass *p = new MyDerivedClass; p->MyBaseClassA MyBaseClassA ::MemFunc(); p->MyBaseClassB MyBaseClassB ::MemFunc(); 多 ?和′? !多 ?是 向 象的 ?? 允许程序在 ? 象的操作时,允许 象 不 同的方式 不同? 象的操作 不同? 象有 ? ‰操作的方”¨ !′? ′? ‰ 多 ?¨ 说 在 说 之前加上 virtual 在基?的说 ¢, ′? virtual void Display(); 调用 CShape *pShape = GetCurrentShape(); pShape->Display(); ′ ! ′ virtual void Display() = 0; !?? –不能生 –在ˉ生?¢必须?¨相˙ ′ 的 ‰ 象的内存分 ! Vptr?ˇ和vtab class A { private : int value; public: virtual void Func1(void) virtual void Func2(void) }; 变? ? value 0 vptr 4 A::Func1 A::Func2 vtab 象的内存分 ( ) class B : pulic A { private : int value1; public: virtual void Func1(void) virtual void Func2(void) }; 变? ? value 0 vptr 4 value1 8 B::Func1 B::Func2 vtab 象的内存分 ( 二) class B : pulic A { private : int value1; public: virtual void Func1(void) }; 变? ? value 0 vptr 4 value1 8 B::Func1 A::Func2 vtab 象的内存分 ( 三) class C { private : int value2; public: virtual void Func3(void) virtual void Func4(void) }; class D : public C { private : int value3; public: virtual void Func3(void) }; class E : public B, public D { private : int value4; public: virtual void Func1(void) virtual void Func4(void) }; 变? ? value 0 vptr 4 value1 8 value2 12 vptr 16 value3 20 value4 24 D::Func3 E::Func4 vtab E::Func1 A::Func2 B E D A C a 系 ! Publica – ?is-a? 系 ! privatea – ?has-a? 系 – ?用… ? 嵌套?来 示 ! protecteda – ¥privatea 宽 ! virtuala – ? ?ˇ – ′基?的? fithe most derived class ? 转换 ! Static_cast ! Dynamic_cast – 向?转换 void Draw(CShape *shape) { //shape->DrawRect() //shape->DrawCircle() if (dynamic_cast<CRect *>(shape)) {…} } ! RTTI typeid Static_cast? 转换 class B { ... }; class D : public B { ... }; void f(B* pb, D* pd) { D* pd2 = static_cast<D*>(pb); // not safe, pb may // point to just B B* pb2 = static_cast<B*>(pd); // safe conversion ... } Static_cast Static_cast ? 转换 ( ) class B { ... }; class D : public B { ... }; void f(B* pb) { D* pd1 = dynamic_cast<D*>(pb); D* pd2 = static_cast<D*>(pb); } C++ a ! C a ! iostream library – cin、cout、cerr – ostream& operator <<(ostream& os, const MyClass) – istream& operator >>(istream& os, MyClass&) ! STL(Standard Template Library) Generic Programming !作 Alexander Stepanov !目 ? 、 `地 ‰各 算” !思想 算”进行抽象,? 示 分开 !???技 为基础 – ?? – ??? ! C++的发展使得这 思想得? ‰ STL基础 ! Object-Based Programming – 有 class的各 计技 ! 象(function objects) – §? 调用操作符()的? !?? – ?? – ??? – ???化 STL思想 ? 算” 容 STL ‰ Iterator 象 容 (Container) 算”(Algorithm) Iterator 象 Iterator 象 STL容 !?序容 (Sequence Container) – vector – deque – list ! 联容 (Associative Container) – set – multiset – map – multiset STL迭代 !迭代 (Iterator)是?ˇ(pointer)的泛化 § 访问 向迭代 向前迭代 输入迭代 输出迭代 STL算” !改变?序的操作 – reverse、replace !不改变?序的操作 – for_each、find ! 序?相 操作 – sort、rotate ! 用的 操作 – count、sum_up 使用STL #include <functional> #include <list> #include <iostream> #include <algorithm> using namespace std; template <typename T> void print_elements(T elem) { cout << elem << " "; } void (*pfi)(int) = print_elements; void main() { int ia[7] = {0,1,2,3,4,5,6}; list<int> ilist(ia, ia+7); // ?陣列做為 list 的'值 for_each(ilist.begin(), ilist.end(), pfi); // 0 1 2 3 4 5 6 ilist.push_back(7); ilist.push_back(0); ilist.push_back(7); ilist.push_back(9); for_each(ilist.begin(), ilist.end(), pfi); // 0 1 2 3 4 5 6 7 0 7 9 ilist.remove_if(bind2nd(modulus<int>(), 2)); // 去 所有奇數 for_each(ilist.begin(), ilist.end(), pfi); // 0 2 4 6 0 } C++参考书 “Design and Evolution of C++” “C++ Programming Language” “C++ Primer”(3/e) “Inside the C++ Object Model” “Effective C++”(2/e) “More Effective C++” “Exceptional C++” “C++ Strategies and Tactics” “Generic Programming and the STL”