解决方案

C++程序设计重点总结(谭浩强版)

seo靠我 2023-09-23 03:24:37

免费分享超过1000本计算机类电子书,包含编程语言、大数据、机器学习、校招面试经验等

(https://github.com/xiaoleetongxue/csbooks)

文章目录

第1章 C++初步知识SEO靠我1.流程 第3章 程序设计1.优先级2.switchbreak continue 第4章 函数1.内置函数2.函数重载3.函数模板4.带默认参数的函数5.动态存储和静态存储6.auto(自动变量、动态SEO靠我存储)7.static(静态局部变量、静态存储)8.register(寄存器变量、在内存)9.extern(外部变量、静态存储、别的文件可引用)10.static(静态外部变量、静态存储、只限本文件中SEO靠我使用)11.内部函数外部函数 第5章 数组1.一维数组2.二维数组3.字符数组4.字符串处理函数5.string6.string [] 第6章 指针和引用1.指针 和 指针变量2.`&` `*`3.指SEO靠我针作为形参4.指向数组5.指针变量 和 指针函数6.指针数组7.const指针* void指针8.指针小结9.引用(本质是指针常量)10.参数传递 第7章 用户自定义数据类型1.结构体类型(`struSEO靠我ct`)2.链表3.`new`和`delete`4.枚举类型(枚举常量)5.typedef声明新类型名 第9章 类和对象1.构造函数2.析构函数3.构造函数、析构函数执行顺序4.对象指针5.this指SEO靠我针6.共享数据的保护7.指向对象的常指针8.指向常对象的指针变量9.对象的常引用10.对象的动态建立和释放11.1 对象赋值11.2 对象复制13.静态成员(static)14.友元友元函数友元类 1SEO靠我5.类模板 第10章 运算符重载(不在考纲内)1.运算符重载规则2.运算符重载函数作为类成员函数3.运算符重载函数作为友元函数4.单目运算符重载5.重载流运算符(必须是友元函数)6.转换构造函数7.类SEO靠我型转换函数 第11章 继承与派生1.派生类构成2.权限3. 派生类的构造函数4. 派生类的析构函数5.多重继承6.虚基类7.基类和派生类的转换8.小结 第12章 多态性和虚函数1.静态多态和动态多态2SEO靠我.虚函数(=基类声明虚函数+基类对象指针调用派生类方法)3.虚析构函数4.纯虚函数5.抽象类6.静态关联和动态关联 第13章 输入输出流1.C++流库2.标准输出流(ostream类的3个对象)3.格SEO靠我式控制4.标准输入流(cin)5.字符输入的成员函数6.istream类的其他成员函数7.文件8.文件流类和文件流对象9.对ASCII码文件的操作10.对二进制文件的操作11.文件指针有关函数

第1章 SEO靠我C++初步知识

1.流程

编辑 -> 编译(.cpp) -> 连接(.obj) -> 运行(.exe) -> 分析结果

第3章 程序设计

1.优先级

! > 算术运算符 > 关系运算符 > &&和|| > 赋值SEO靠我运算符

2.switch

switch(表达式) {case 常量表达式1: 语句1; break;case 常量表达式2: 语句2; break;...default: 语句; breaSEO靠我k; }

break continue

while(表达式1) {if()continue; //结束本次循环,继续下次循环if()break; //结束全部循环 SEO靠我 } 表达式可以是数值类型包括字符类型数据次序不影响结果case表达式的值必须互不相同

第4章 函数

C++在程序进行编译时,以程序文件模块为编译单位

1.内置函数

编译时将调用函数SEO靠我的代码直接嵌入到主调函数中,而不是将流程转出去

inline int max(int, int, int);inline int max(int a, int b, int c) {..SEO靠我. } 规模小使用频繁不包含复杂控制语句,如循环语句和switch语句建议性,而非指令性

2.函数重载

重载函数的参数格式、参数类型、参数顺序三者中必须至少有一种不同,返SEO靠我回值类型可同可不同

3.函数模板

函数模板只适用于函数体相同、函数的参数相同而类型不同的情况

如果参数的个数不同,则不能用函数模板。template <typename T> T max(TSEO靠我 a, T b, T c) {... }

4.带默认参数的函数

实参和形参的结合是从左至右,指定默认值的参数必须放在形参列表的最右边声明中给出默认值,定义时可以省略一个函数SEO靠我不能既作为重载函数,又作为有默认参数的函数

5.动态存储和静态存储

动态存储:动态分配空间静态存储:分配固定空间

6.auto(自动变量、动态存储)

int f(int a) {auto inSEO靠我t b, c = 3; //自动变量,默认为auto,可省略 } f函数被调用结束后,变量被销毁不赋初值,则它的值是个不确定的值

7.static(静态局部变量、静态存SEO靠我储)

int f(int a) {static int b = 0; //静态局部变量 } f函数被调用结束后,变量保留,外边不可以调用不赋初值,编译时SEO靠我自动赋值0或空字符

8.register(寄存器变量、在内存)

int f(int a) {register int i=1; //寄存器变量 } 使用频SEO靠我繁的可以声明为寄存器变量建议性,而非强制性

9.extern(外部变量、静态存储、别的文件可引用)

1.在一个文件内声明全局变量

int main() {extern int a, b; /SEO靠我/全局变量的提前引用声明cout<<a<<b<<endl; } int a = 15, b = -8; //全局变量

2.在多文件的程序中声明外部变量

file1.cpp

iSEO靠我nt a=3, b=4; ...

file2.cpp

extern int a, b; //在编译连接成一个程序后,将file1.cpp中的a、b作用域扩展到file2.cppint maSEO靠我in() {cout<<a<<" "<<b<<endl; }

10.static(静态外部变量、静态存储、只限本文件中使用)

file1.cpp

static int a =SEO靠我 3; //静态外部变量,只限于本文件中用

file2.cpp

extern int a; //引用不到file2.cpp中的a,因为是静态外部变量 int main() SEO靠我{cout<<a<<endl; }

11.内部函数外部函数

内部函数:函数只能被本文件

中的其他函数调用 static int func(int a, int b) SEO靠我 {... } 外部函数:可供其他函数调用,默认都是外部函数

file1.cpp int max(int x, iSEO靠我nt y) {... }

file2.cpp

int main() {extern int max(int, int); //声明要调用其他文件中的max函SEO靠我数max(1, 2); }

第5章 数组

字符串结束标志符\0(ASCII码为0)

1.一维数组

int a[10]; //不允许对数组的大小作动态定义const int n = 5; SEO靠我 int a[n]; //合法,因为n是常量

2.二维数组

int a[3][4]; int a[][4] = {1, 2, 3, 4, 5, 6}//第2维的长度不能省略

3.字符SEO靠我数组

char a[10] = {I, a, m, h, a, p, p, y}; char c[] = "I am happy"; //正确 c = a; //错误 SEO靠我 c = {I, a, m, h, a, p, p, y}; //错误 c[0] = I; //正确char str[20]; cin>>str; //输入SEO靠我字符串 cout<<str; //输出字符串 遇到\0结束,不包括\0

4.字符串处理函数

#include <string.h> 或 #include <SEO靠我string> strcat:字符串连接函数 strcat() strcpy:字符串复制函数(覆盖) char str1[10], SEO靠我str2[] = "China"; strcpy(str1, str2); //第1个实参必须是数组名,第2个实参可以是数组名,也可以是字符串常量 strcpy(strSEO靠我1, "China");strcpy(str1, str2, 2); //将str2中前面2个字符复制到str1中去,然后加上\0 strcmp:字符串比较函数 stSEO靠我rcmp(str1, str2); //正确 strcmp("China", "Korea"); //正确 strcmp(str1, "Beijing"); //正确

SEO靠我1 == 串2,返回0

串1 > 串2,返回正数

串1 < 串2,返回负数strlen:字符串长度函数 char str[10] = "China"; cout<<strlSEO靠我en(str); //5 不包含\0

5.string

string不是C++本身的基本类型,而是C++标准库中声明的一个字符串类

需要引入头文件 #include <string> SEO靠我 定义 string s1, s2; s1 = "Hello"; s2[0] = a; //合法修改第一个字符 输入输出 SEO靠我 cin>>s1; cout<<s1; 运算 string s1, s2; s1 = "Hello"; sSEO靠我2 = s1; //赋值运算 s2 = s1 + s2; //连接 if(s1 > s2) ...; //比较运算符

6.string []

string name[3] SEO靠我= {"Zhang", "Li", "Sun"};

第6章 指针和引用

1.指针 和 指针变量

变量的指针:变量的地址指针变量:一个变量专门存放地址(指针)

2.& *

自右向左结合

int a = 10; SEO靠我 int *pointer_1, *pointer_2; pointer_1=&a; pointer_2 = &*pointer_1; //从右向左执行,将aSEO靠我的地址赋给pointer_2

3.指针作为形参

调用函数时不会改变实参指针变量的值(地址),但可改变实参指针变量所指向的值

int a = 10 int *p = a; fuSEO靠我n(p); int fun(int *p){} //不改变p的值,但可改变a的值

4.指向数组

启示指向的是数组的第一个元素

int a[10]; int *p;p=&a[0SEO靠我]; //等价于 p=a;p+1 //表示数组的下一个元素void select_sort(int array[], int n) //等价于 void select_SEO靠我sort(int *array, int n)

5.指针变量 和 指针函数

指针变量(2个括号)【是变量】 int a=1, b=1; int max(int x, intSEO靠我 y);int (*p)(int, int); // 是变量,可以指向函数 p=max p(a, b) //用函数指针调用 等价于 max(a, b) SEO靠我 指针函数(1个括号)【是函数】 int *p(int x, int y) {} // 是函数,返回值为int型指针

6.指针数组

int *p[4]; //每个元素都是指SEO靠我针类型 相当于: int *p0; int *p1; int *p2; int *p3;例: char *name[] = {"peter", "jacSEO靠我k", "smith"}; //指针数组

[]优先级比*高

注意:int (*p)[4]; //指向一维数组的指针变量 用来指向二维数组 #include<iostream> SEO靠我 using namespace std;int main() {int w[3][4] = {{1,2,3, 11}, {4,5,6, 12}, {7,8,9, 13}};intSEO靠我 (*p)[4] = w; //指向一维数组的指针变量for(int i=0; i<3; i++){for(int j=0; j<4; j++)cout<<p[i][j]<<" ";cout<<endSEO靠我l;}return 0; }

7.const指针

指向常量的指针变量(量不能变) const int *p = &a; // 不允许通过p修改a的值 *p SEO靠我= 10; //非法 p = &b; //合法 常指针(指针不能变) int * const p = &a; //不允许修改p的指向,但允许修改a的值SEO靠我;定义时要初始化 *p = 10; //合法 p = &b; //非法 指向常量的常指针(量不能变,指针也不能变)

1.常变量

只能由 [指向常变量的指针SEO靠我变量] 指向它,不能用 [一般指针]

2.[指向常变量的指针变量] 也可以指向[一般变量],那么用该指针变量访问时有常变量的特征

3.[一般指针]只能指向[一般变量]const int * const pSEO靠我 = &a; *p = 10; //非法 p = &b; //非法

* void指针

不指向任何类型 = 指向空类型 = 指向不确定的类型

可以把非void型的指针赋给voiSEO靠我d型指针变量,但不能把void型指针直接赋给非void型,必须先进行强制转换

int a = 3; int *p1 = &a; char *p2 = "new"; SEO靠我 void *p3; p3 = (void *)p1; //将p1的值转换为void *类型,赋给p3 cout<<*p3<<endl; //p3不能执行确定类SEO靠我型的变量,非法 cout<<p3<<endl; //a的纯地址,但p3并不指向acout<<*(int *)p3<<endl; //把p3的值转换为(int *)型,可以指向变量a SEO靠我 int main() {int a = 3;int *p1 = &a;void *p2 = p1;cout<<p2<<endl; //0x6ffe44 p2是a的纯地址SEO靠我,但p2并不指向a,所以*p2是非法的 cout<<&a<<endl; //0x6ffe44 a的地址 cout<<&p2<<endl; //0x6ffe38 p2指针变量自己的地址 return 0SEO靠我; }

8.指针小结

定义类型含义int *p;int *p为指针变量,指向int型数据int *p[4];int *[4]p为指针数组,指向4个元素都是int型指针的数组int (*p)SEO靠我[4];int (*)[4]p为指针变量,指向4个int数据的一维数组int *p ();int * ()p为正常函数,只是函数返回值为int型指针int (*p)();int (*)()p为指针变量SEO靠我,指向函数int **p;int **p为指针变量,指向一个指针(该指针指向int型数据)int * const pint * constp是指针变量,常指针,指向不能变const int *p

intSEO靠我 const * pconst int *p是指针变量,指向常量,不能通过p修改值const int * const pconst int * constp是指针变量,指向不能变且也不能通过p修改值vSEO靠我oid *pvoid *p是指针变量,基类型为空(void),不指向具体对象

9.引用(本质是指针常量)

变量的“别名”

int a; int &b = a; /* 引用只有声明,没有定义 SEO靠我*/int &b; /* 非法!引用声明的同时必须初始化 */int a1, a2; int &b = a1; int &b = a2; /* 非法!引用声明后不能变更SEO靠我 */int a[5]; int &b[5] = a; //非法!不能建立引用数组 int &c[5] = a[0]; //非法!不能作为数组元素的别名int a; SEO靠我 int &b = a; int *p = b; //非法!不能建立指向引用的指针int a; int &b = a; int *p = &SEO靠我b; //合法,&b是a的地址

10.参数传递

变量名作形参(值传递) void swap(int a, int b) {... }void main(){int i=1,SEO靠我 j=2;swap(i, j); } 指针作形参(值传递) void swap(int *p1, int *p2){... }voidSEO靠我 main(){int i=1, j=2;swap(&i, &j); } 引用作形参(地址传递) void swap(int &a, int &b){SEO靠我... }void main(){int i=1, j=2;swap(i, j); }

第7章 用户自定义数据类型

1.结构体类型(struct)

struct StudenSEO靠我t {int num;char name[20];char sex; } student1 = {1001, "Zhangsan", M}; //最后一个分号不能少!!SEO靠我!Student student2 = {1002, "Wangwu", F};student1 = student2; //相同结构体类型变量可相互赋值student.num = 10010; //SEO靠我"."是成员运算符Student stu[3] = {1001, "Jack", M, 1002, "Peter", F, 1003, "mali", M}; //结构体数组Student *p = SEO靠我&student1; //结构体指针等价 student1.num; (*p).num; // "." > "*" p->num; // "->" > SEO靠我"++" p->num++; //得到num后,使用完加1 ++p->num; //等到num,加1后使用

2.链表

见考试大纲

3.new和delete

int *p1 = SEO靠我new int(100); //整型数 int *p2 = new int[10]; //整型数组delete p1; //释放变量 delete [] p2; //释SEO靠我放数组

4.枚举类型(枚举常量)

enum weekday{sun=7, mon=1, tue, wed, thu, fri, sat}; //tue为2,wed为3...往后加1Weekday workSEO靠我day;workday = tue; //正确 workday = 2; //错误 workday = (Weekday)2; //C语言风格强制类型转化 SEO靠我 workday = Weekday(2); //C++风格强制类型转化

5.typedef声明新类型名

typedef int INTEGER; INTERGER I;typedef SEO靠我int NUM[100]; //声明NUM为整型数组类型,包含100元素 NUM n;typedef char *STRING; //声明STRING为char *类型,即字符指针类型SEO靠我 STRING p;typedef int (*POINTER)(); //声明POINTER为指向函数的指针,函数返回整数值 POINTER P;typedef stSEO靠我ruct {int month;int day;int year; } DATE; //声明DATE为结构体类型 DATE birthday;

第9章 类SEO靠我和对象

1.构造函数

格式:

class Student {private:int num;int score;char name[20];public:Student(){} //无参构造SEO靠我函数Student(int n) //一个参数的构造函数{num = n;score = 0;strcpy(name, "123");}Student(char nam[], int n=0, intSEO靠我 score=0) //默认参数的构造函数{num = n;score = n;strcpy(name, nam);}Student(int n, int s, char nam[]):num(n),SEO靠我 score(s){strcpy(name, nam);} //参数初始化列表}

注意项:

构造函数名必须与类名同名无返回值,无类型自动调用,用户不能显式调用 Student s; //正SEO靠我确 Student s(); //错误!不能显式调用 系统可自动生成无参构造函数数据成员是数组时,不能用参数初始化列表,要用正常函数体初始化带默认参数的构造函数,默认SEO靠我值在声明时给出 Student(int = 1001, int = 20); //省略形参名声明合法 一个类只能有一个默认构造函数//下面两同时存在是错误的!二义性 SEO靠我 Stduent(); Student(int num=10, int score=0);Student s; //产生二义性 [构造函数重载] 和 [SEO靠我带默认参数的构造函数] 不能同时存在 //产生二义性 Box(); Box(int, int); Box(int =10, int =1SEO靠我0, int =10);

2.析构函数

4种情况下执行析构函数:

函数内定义的局部对象:函数调用结束时释放前执行静态局部对象:main函数结束或exit函数结束时调用全局对象:main函数结束或exit函数SEO靠我结束时调用new运算符动态建立的对象:在delete运算符释放该对象之前

析构函数不是删除对象,只是在撤销对象占用的内存之前完成一些清理工作

析构函数没有返回值;没有函数类型;没有函数参数;不能被重载。一SEO靠我个类只能由一个析构函数编译系统会自动生成一个析构函数(do nothing)

3.构造函数、析构函数执行顺序

先构造的后析构,后构造的先析构

4.对象指针

Time *pt; Time t1;SEO靠我 pt = &ti;//等价于 (*pt).hour; pt->hour; // "->"是指针专用的

成员函数指针变量:

void (Time::*p2)SEO靠我(); p2=&Time::get_time;

要求三个匹配

函数参数的类型和参数个数函数返回值的类型所属的类

5.this指针

每个成员函数都包含一个特殊的指针,指向本类对象的指针,他的值是SEO靠我当前被调用的成员函数所在的对象的起始地址。

//等价于 (*this).height this->height height

优先级:"." > “*”

6.SEO靠我共享数据的保护

常对象

//等价 Time const t1(12, 34, 46); const Time t1(12, 34, 46); 常对象必须SEO靠我始化,整个对象生命周期中,数据成员的值不能改变常对象只能调用常成员函数常成员函数可以访问常对象中的数据成员,但不许改变他的值一定要改常对象中的某个数据成员值 mutable int cSEO靠我ount; //mutable 可变数据成员

常数据成员(访问不限,不可改值)

class Time {const int hour; } 只能通过构造函SEO靠我数的参数初始化表初始化任何其他函数都不能改变它的值

常成员函数(访问不限,不可改值)

class Time {void get_time() const; } SEO靠我 只能引用本类的数据成员,但不能改变值不能调用另一个非const的成员函数

7.指向对象的常指针

Time t1(19 ,12, 15); Time * const p1; SEO靠我 p1 = &t1; 指向对象的常指针,指向后,不允许改变指向但可以改变对象的数据成员做形参使用:保护指向在函数运行期不允许改变指向void fun(Time * const tSEO靠我);

8.指向常对象的指针变量

同 指向常变量的指针变量

常对象只能由[指向常对象的指针变量]指向,不能由[一般指针]指向使用[指向常对象的指针变量]时,有常量特征,不能改变值做形参使用:保护指向的对象在执SEO靠我行中不改变值 void fun(const Time *t);

9.对象的常引用

void fun(const Time &t); //t所指向的变量的值不能变

10.对象的动态建立和释放

TSEO靠我ime *t = new Time; delete t; //在释放内存空间前,自动调用析构函数

11.1 对象赋值

Time t1, t2; ... t1SEO靠我 = t2; //同属一类的两个对象可相互赋值 类的数据成员中不能包括动态分配的数据,否则赋值有问题

11.2 对象复制

Box::Box(const Box&b) //复制构造函数 注SEO靠我意参数是引用!! {height = b.height;width =b.width; }...Box box2(box1); //对象复制 复制构造SEO靠我函数:只有1个参数,一般是const对象引用编译系统自动提供一个复制构造函数 对象复制对象赋值从无到有建立新对象对已存在的对象进行赋值

对象复制的使用场景:

1.建立新对象 SEO靠我 Box box1(12, 15, 16); Box box2(box1); //建立新对象box2 2.函数参数为类对象 void fun(Box SEO靠我b) //函数调用时的虚实结合 {... } 3.函数的返回值是类的对象 Box f() {Box box(12, 2SEO靠我, 4);return box; //赋值给一个“临时对象”返回给函数调用处 }int main() {Box b = f();return 0; }

1SEO靠我3.静态成员(static)

归属于类,所有该类的对象所共有 class Box {public:static int height; //静态数据成员staitc inSEO靠我t volume(); //静态成员函数 }int Box::height = 10; //静态数据成员只能在类体外进行初始化int Box::volume() {reSEO靠我turn height; }int main() {Box a;//静态成员a.height; //可以,通过对象引用Box::height; //也可以,通过类名引用SEO靠我//静态成员函数a.volume(); Box::volume();return 0; }

静态成员

内存中只占一份空间,程序运行开始时分配空间静态数据成员只能在类体外进行初始化静态数据成SEO靠我员未赋初值,默认赋0静态数据成员可被对象名引用,也可通过类名引用静态数据成员同样受访问权限控制

静态成员函数

因:静态成员函数没有this指针果:静态成员函数不能直接访问本类非静态成员一定要访问非静态成员SEO靠我,通过对象名.非静态成员函数

14.友元

友元函数

友元函数可以访问该类的私有成员

1.普通函数作为友元函数

class Time {private:int hour; public:frienSEO靠我d void display(Time &); //友元函数(不属于该类) }void display(Time &t) //普通函数 {t.hour; //可以通过对SEO靠我象名访问私有成员 } 引用私有成员要用对象名.数据成员没有this指针

2.一个类的成员函数,作为另一个类的友元函数

class Date; //提前引用声明/* 客人 SEO靠我*/ class Time {private:int hour;public:void display(Date &); //正常成员函数 }/* 主人SEO靠我 */ class Date {private:int hour;public:friend void Time::display(Date &); //Time类中的SEO靠我display函数作为本类的友元函数 }void Time::display(Date &d) {d.hour; // 别人家的私有数据成员hour; //自己家的私有SEO靠我数据成员 }

注意项:

声明友元函数时,加上该函数所属的类引用别人地私有成员要通过对象名.数据成员

友元类

//B是A的友元类,B中的所有成员函数都是A的友元函数 class SEO靠我B; class A { public:friend class B; //B是A的友元类 }class B {... SEO靠我} 友元关系不能被继承友元关系是单向的,且不具有传递性

15.类模板

功能相同,只是数据类型不同

template <class T> class Compare SEO靠我 {public:Compare(T a, T b) //构造函数{x=a;y=b;}T max() //成员函数类内定义 { return (x>y)?x:y; }T min();privatSEO靠我e:T x, y; }template<class T> T Compare<T>::min() //类外定义 { return (x>y)?x:y;}SEO靠我int main() {Compare<int> f1(3, 7); Compare<double> f2(45.2, 30.1);return 0; }

三部曲:

1.写SEO靠我个实际的类2.虚拟类名替换具体类名3.第一行加入template <class 虚拟类名>

多个类型参数的情况:

template <class T1, class T2> class BSEO靠我ox {... } 类模板模板类重点是模板,产生类的模子重点是类,由模板产生的类

第10章 运算符重载(不在考纲内)

1.运算符重载规则

运算符重载实质是SEO靠我数重载 int operator+ (int a, int b) {return (a+b); } 不能重载的5个运算符

. * :: sizeof ?:SEO靠我

重载不能改变运算符运算对象(即操作数)个数重载不能改变运算符的优先级别重载不能改变运算符的结合性重载运算符的函数不能有默认的参数重载运算符必须至少一个参数是类的对象(或是类对象的引用),不能都是C++SEO靠我标准类型,以防止用户修改用于标准类型数据的运算符的性质用于类对象的运算符一般必须重载,除了“=” “&”

2.运算符重载函数作为类成员函数

第一个参数是this指针隐式调用的访问

class ComplexSEO靠我 {private:double real;double imag;public:Complex operator+(Complex &c2); //成员函数运算符重载函数 SEO靠我 };Complex Complex::operator+(Complex &c2) {Complex c;c.real = real + c2.real;c.imag = imaSEO靠我g + c2.imag;return c; } “=” “[]” “()” "->"必须作为成员函数重载

3.运算符重载函数作为友元函数

没有this指针

class CoSEO靠我mplex {private:double real;double imag;public:friend Complex operator+(Complex &c1, Complex SEO靠我&c2); //友元函数运算符重载函数 };Complex operator+(Complex &c1, Complex &c2) {Complex c;c.real SEO靠我= c1.real + c2.real;c.imag = c1.imag + c2.imag;return c; } “<<” “>>” 只能用友元函数重载

4.单目运SEO靠我算符重载

C++规定 有一个int型形参的重载函数,是后置自增自减运算函数

class Time {private:int minute;int sec;public:Time operaSEO靠我tor++(); //++iTime operator++(int); //i++ };Time Time::operator++() //++i {if(++sec SEO靠我>= 60){sec-=60;++minute;}return *this; }Time Time::operator++(int) //i++ {Time temp(SEO靠我*this); //临时对象 保存自加前的状态sec++;if(sec >= 60){sec-=60;++minute;}return temp; //返回的是自加前的对象 }

5.重载SEO靠我流运算符(必须是友元函数)

class Complex {private:double real;double imag;public:friend ostream& operator<SEO靠我< (ostream & , Complex & );friend istream& operator>> (istream & , Complex & ); };ostream& oSEO靠我perator<<(ostream &output, Complex& c) {output<< "(" << c.real << "+" <<c.imag <<"i)" <<endlSEO靠我;return output; }istream& operator>>(istream& input, Complex& c) {cout<<"please inpuSEO靠我t real part and imaginary part of complex number:";input >> c.real >> c.imag; return input; SEO靠我}

6.转换构造函数

只有一个参数,如果有多个参数,他就不是转换构造函数

class Complex {private:double real;double imag;public:CompSEO靠我lex(double r){real = r; //将double型r转换为Complex类的对象imag = 0;} }

7.类型转换函数

class Complex {SEO靠我private:double real;double imag;public:operator double(){return real;} } 类型转换函数函数名为SEO靠我operator double返回值类型由函数名中指定类型名确定只能作为成员函数

第11章 继承与派生

1.派生类构成

派生类把基类的全部成员接受过来(不包括构造函数析构函数)调整从基类接收的成员

若派生类SEO靠我中声明一个与基类成员同名成员,则派生类中的新成员会覆盖基类的同名成员;对于成员函数要考虑函数重载的情况。

派生类新增加的成员

2.权限

基类成员在基类的访问属性继承方式基类成员在派生类的访问属性publicSEO靠我publicpublicprotectedpublicprotectedprivatepublic不可访问publicprotectedprotectedprotectedprotectedproteSEO靠我ctedprivateprotected不可访问publicprivateprivateprotectedprivateprivateprivateprivate不可访问 派生类中访问SEO靠我属性在派生类中在派生类外部在下一层公用派生类public可以可以可以protected可以不可以可以private可以不可以不可以不可访问不可以不可以不可以

3. 派生类的构造函数

派生类的构造函数

继承过SEO靠我来的基类成员初始化工作由派生类构造函数负责 Class A //基类 {private:int x, y;public:A(int a, int b) //基类构造函数SEO靠我{x=a;y=b;} };/* 形式1: */ class B:public A //派生类 {private:int z;public:B(int aSEO靠我, int b, int c):A(a, b) //派生类构造函数{z=c;} };/* 形式2 */ class B:public A //派生类 {SEO靠我private:int z;public:B(int a, int b, int c); //派生类构造函数声明 };//类外定义 B::B(int a, int b,SEO靠我 int c):A(a, b) {z=c; }

构造函数执行顺序:

1.基类构造函数(基类数据成员初始化)2.子对象构造函数(子对象数据成员初始化)3.派生类构造函数(派生SEO靠我类数据成员初始化)

派生类只需写其上一层派生类的构造函数,不必每一层都写出来

派生类构造函数特殊形式

当不需要对派生类新增成员操作时,派生类构造函数的函数体可为空当基类中没有定义构造函数或定义了没有参数的构SEO靠我造函数,派生类构造函数可不写基类构造函数(系统默认调用基类默认构造函数)当基类、子对象、派生类都不需要参数,派生类可以省略显式构造函数,系统调用默认的构造函数当基类或子对象中定义了带参数的构造函数,则SEO靠我派生类必须显式的定义构造函数

4. 派生类的析构函数

析构函数执行顺序:

1.派生类自己的析构函数(处理新增成员)2.子对象的析构函数(处理子对象)3.基类的析构函数(处理继承的成员)

5.多重继承

classSEO靠我 D: public A, public B, protected C {... };

多重继承构造函数调用顺序:

1.调用基类的构造函数,调用次序按照他们继承时说明的次序SEO靠我(从左往右)2.调用子对象的构造函数,调用次序按照它们在类中说明的次序(从上到下)3.调用派生类的构造函数

多重继承析构函数调用顺序:

与多继承构造函数调用顺序相反

6.虚基类

在继承间接共同基类时,只保留SEO靠我份基类成员

class A //基类 {}; class B : virtual public A //B是A的公有派生类,A是B的虚基类 {}; SEO靠我 class C : virtual public A //C是A的公有派生类,A是C的虚基类 {}; 虚基类实在声明派生类时,指定继承方式时声明的为保证虚拟SEO靠我类在派生类只继承一次,该虚基类的所有直接派生类都要声明为虚基类

虚基类的初始化

class A //基类A {A(int i){}; };class B : virtualSEO靠我 public A //A是B的虚基类 {B(int n): A(n){} };class C : virtual public A //A是C的虚基类 SEO靠我 {C(int n):A(n){} };class D : public B, public C //正常继承 {D(int n): A(n), B(n), C(n){SEO靠我} //D中要对所有基类初始化;重要!也就是还要对虚基类A初始化 }; 在最后的派生类中不仅要负责对直接基类初始化,还要负责虚基类的初始化!!!编译系统只执行最后派生SEO靠我类的构造函数调用,忽略虚基类的其他派生类(B和C)

7.基类和派生类的转换

只有公有派生类才是基类的真正子类型,它完整的继承了基类的功能

1.派生类对象可以向基类对象赋值

儿子可以给爸爸赋值,反之不对

A a1SEO靠我; //基类A B b1; //A的派生类B a1 = b1; //舍弃派生类自己独有的成员,“大材小用” 2.派生类对象可以替代基类对象向基类对象的SEO靠我引用进行赋值或初始化 A a1; B b1; A &r = b1; //指的是b1中基类的那一部分的别名 3.函数参数是基类对象或基类SEO靠我对象引用,实参可以用子类对象 void fun(A &r){} fun(b1); //正确 只输出派生类中的基类成员 4.指向基类对象的指针变量也可以SEO靠我指向派生类对象(重要)

指向儿子中继承的那一部分成员

A *p1; B b; p1 = &b; //指向B中继承A的那部分数据

8.小结

类的继承派生体现的是 “是”的关系

类的SEO靠我组合(子对象)体现的是“有”的关系

继承时纵向的,组合是横向的

第12章 多态性和虚函数

1.静态多态和动态多态

静态多态性动态多态性通过函数重载实现,编译时多态通过虚函数实现,运行时多态 虚SEO靠我函数函数重载函数首部是相同的函数首部是不同的(参数个数或类型)

2.虚函数(=基类声明虚函数+基类对象指针调用派生类方法)

同一类族中不同类的对象,对同一函数调用作出不同的响应

#include <iostSEO靠我ream> using namespace std;class Student {protected:int num;public:Student(int n):numSEO靠我(n){};virtual void display() //虚函数{cout<<num<<endl;} };class Graduate:public Student SEO靠我 {private:float wage;public:Graduate(int n, float m):Student(n),wage(m){};void display() //派生类重新定义虚函SEO靠我数{cout<<num<<" "<<wage<<endl;} };int main() {Student s(1001);Graduate g(1001, 4500.5SEO靠我);Student *p = &s; p->display();p=&g; //父类指针指向子类/* 若display不是虚函数,那么只能调到父类的display方法;若display在基类中被声明为SEO靠我虚函数,那么可以通过父类指针调到子类的display函数*/p->display(); return 0; }

1001

1001 4500.5

使用虚函数

类外定义虚函数不必要加上virtuSEO靠我al基类成员函数被声明为虚函数,其派生类的同名函数自动成为虚函数,vitual可加可不加定义基类对象指针,指向同一类族;指谁调谁(调用的是指向对象的同名函数)虚函数+指向基类对象指针 = 动态多态性

3SEO靠我.虚析构函数

未声明为虚析构函数时,new 出来的对象,delete时只会调用基类的析构函数

#include <iostream> using namespace std;class PSEO靠我oint {public:Point(){}virtual ~Point() //虚析构函数{cout<<"executing Point destructor"<<endl;} SEO靠我 };class Circle:public Point {public:Circle(){}~Circle(){cout<<"executing Circle destruSEO靠我ctor"<<endl;}private:int radus; };int main() {Point *p = new Circle; //动态分配空间delete SEO靠我p;return 0; }

executing Circle destructor

executing Point destructor 先调用派生类析构函数,再调用基类析构函数基类析构函数SEO靠我声明为虚函数后,该基类的所有派生类的析构函数都声明为虚函数构造函数不能被声明为虚函数!!!

4.纯虚函数

virtual float area() const = 0; 纯虚函数没有函数SEO靠我体最后的"=0"不表示返回值为0这是个声明语句最后要加";"基类声明了纯虚函数,派生类没有对该函数定义,那么该虚函数在派生类中仍然是纯虚函数

5.抽象类

定义抽象类的目的:用它作为基类去建立派生类

凡是包含SEO靠我纯虚函数的类都是抽象类包含纯虚函数的类是无法建立对象的

6.静态关联和动态关联

动态关联

通过基类指针调用虚函数(pt->shapeName()),在运行阶段才能确定是哪一类的虚函数。

静态关联

通过对象名调用SEO靠我虚函数(point.shapeName()),在编译阶段就能确定是哪一个类的虚函数

第13章 输入输出流

标准输入输出(标准I/O)文件输入输出(文件I/O)串I/O

1.C++流库

两个基类

ios类(负责高SEO靠我层操作,面向用户)streambuf类(负责低层操作,面向底层)

有关头文件

iostream:输入输出流fstream:文件I/Ostrstream:字符串I/Ostdiostream:混合C和C++iSEO靠我omanip:格式化I/O用

2.标准输出流(ostream类的3个对象)

coutcerr(只能输出显示器,不经过缓冲区)clog(存放在缓冲区,当缓冲区满了或遇到endl,向显示器输出)

3.格式控制

SEO靠我文件#include <iomanip>

用流对象的成员函数控制

precision(n); //实数精度为n为 width(n); //字段宽度n位 fill(c); /SEO靠我/设置填充字符c

设置格式

setf(); //设置格式 unsetf(); //取消设置格式 参数: iso::left iso::decSEO靠我 //整数基数是10 iso::oct //整数基数是8 iso::hex //整数基数是16

成员函数width(n)和setw(n)只对其后面第1个输出项有效

要重新设SEO靠我置格式setf(),先取消usetf()

setf()可以设置多个 setf(ios::internal | ios::showpos)

成员函数put()

专门用于输出单个字符的成员函数put

cout.pSEO靠我ut(A);

4.标准输入流(cin)

键盘输入完按Enter后输入,跳过空格、Tab键、换行符等空白字符

if(!cin)cout<<"error";

5.字符输入的成员函数

get()读入一个字符

当遇到输入SEO靠我流中的文件结束符,函数返回EOF,即**-1**

#include <iostream> using namespace std;int main {int c;whilSEO靠我e( ( c = cin.get() )!=EOF )cout.put(c);return 0; } cin.get(ch); //从输入流中读取一个字符,赋给chSEO靠我/* 等价 */ cin.get(字符数组, 字符个数n, 终止字符); //从输入流中读取n-1字符,赋给字符数组 n-1个有效字符和一个\0 cin.getlineSEO靠我(字符数组, 字符个数n, 终止字符);

6.istream类的其他成员函数

eof()

文件结束返回 非零

文件没结束返回 0#include <iostream> using namespSEO靠我ace std;int main() {char c;while( !cin.eof() ) //eof()为假表示未遇到文件结束符if( (c=cin.get())!= ) //检查SEO靠我读入的字符是否为空格字符cout.put(c);return 0; } peek() 观察 c = cin.peek(); //返回指针当前指向的字符SEO靠我 putback() cin.putback(ch); //将ch插在当前指针之后的位置(注意是插入,不是覆盖) ignore() SEO靠我cin.ignore(n, 终止字符) ; //跳过n个字符或者 终止字符以前的都被忽略 #include <iostream> using namespace stSEO靠我d;int main() {char ch[20];cin.ignore(18, A);cin.get(ch, 20, /);cout<<ch<<endl;return 0; SEO靠我 }

abcA123/

123

7.文件

文件两大类:

程序文件数据文件

根据文件中数据的组织形式分:

ASCII文件 1个字节(8位)存放1个字符(文本文件、字符文件)二进制文件(内部格式文件、字节文件)

ISEO靠我/O功能

低级I/O:以字节为单位输入输出(二进制形式)高级I/O:有意义单位输出(ASCII字符)

8.文件流类和文件流对象

ifstream:从istream派生来。支持从磁盘文件输入ofstream:SEO靠我从ostream派生来。支持向磁盘文件输出fstream: 从iostream派生来。支持对磁盘文件的输入输入

1.打开文件

ofstream outfile; outfile.open(SEO靠我"f1.dat", ios::out); //以输出方式打开一个文件 方式作用ios::in以输入方式打开文件ios::out以输出方式打开文件(默认方式),如果已有此名字的文件,则SEO靠我将其原有的内容全部清除ios::app以输出方式打开文件,追加写ios::ate打开已有文件,文件指针指向文件末尾ios::trunc打开文件,若如果文件存在,则删除其中的全部数据;如果不存在,则建立SEO靠我新文件。ios::out方式的默认格式ios::binary二进制格式打开文件,若没指定则默认ASCII方式打开ios::nocreate打开一个已有文件,如文件不存在,则打开失败ios::norepSEO靠我lace如果文件不存在则建立新文件,如果文件存在则操作失败ios::in | ios::out以输入输出方式打开文件,可读可写ios::out | ios::binary以二进制输出方式打开文件iosSEO靠我::in | ios::binary以二进制输入方式打开文件 不能组合互斥的方式,如:ios::nocreate | ios::noreplace //检测文件打开是否SEO靠我失败 if(outfile.open("f1.dat", ios::app) ==0)cout<<"open error";if( !outfile.open("f1.dat", ioSEO靠我s::app) )cout<<"open error";outfile.close(); //关闭文件

9.对ASCII码文件的操作

例. 键盘输入10个整数送到数组,在将数组存到磁盘文件

#includeSEO靠我 <iostream> #include <fstream> using namespace std;int main() {int a[10];ofsSEO靠我tream outfile("d:\\f1.dat", ios::out); //输出格式打开文件 if( !outfile ) //判断是否打开成功,打开失败时返回0 {cerr<<"open erSEO靠我ror!"<<endl;exit(1); }cout<<"enter 10 numbers:"<<endl;for(int i=0; i<10; i++){cin>>a[i];outfile<<a[iSEO靠我]<<" ";}outfile.close(); //关闭文件 return 0; }

10.对二进制文件的操作

与ASCII码文件不同

既能做输入又能输出的文件

istream &read(SEO靠我char *buffer, int len); //读 ostream &write(const char *buffer, int len); //写 #incluSEO靠我de <iostream> #include <fstream> using namespace std;struct Student {char naSEO靠我me[20];int num;int age;char sex; };int main() {Student stu[2] = {{"Li", 1001, 18, f}SEO靠我, {"Wang", 1002, 17, f}};//输出到磁盘文件 ofstream outfile("d:\\stu.dat", ios::binary);if(!outfile){cerr<<"SEO靠我open error"<<endl;abort(); //退出程序 }for(int i=0; i<3; i++)outfile.write( (char *)&stu[i], sizeof(stu[SEO靠我i])); //要强制转化为 char * outfile.close(); //关闭输出流 //从磁盘文件读取数据Student stu2[2];ifstream infile("d:\\stu.dSEO靠我at", ios::binary);if(!infile){cerr<<"open error"<<endl;abort();} for(int j=0; j<3; j++)infile.read( SEO靠我(char *)&stu2[j], sizeof(stu2[j]));infile.close(); //关闭输出流 //打印读出来的数据 for(int k=0; k<2; k++)cout<<stSEO靠我u2[k].num<<" "<<stu2[k].name<<" "<<stu2[k].age<<" "<<stu2[k].sex<<endl;return 0; }

1001 Li 18SEO靠我 f

1002 Wang 17 f

11.文件指针有关函数

infile.seekg(100); //输入文件位置标记向前移动100字节位置 infile.seekg(-50, ios::cSEO靠我ur); //输入文件中位置标记从当前位置后移50字节 outfile.seekp(-75, ios::end); //输出文件中位置标记从文件尾后移50字节

免费分享超过1000本计算SEO靠我机类电子书,包含编程语言、大数据、机器学习、校招面试经验等

(https://github.com/xiaoleetongxue/csbooks)

更多考研资料、调剂技巧可以关注我的公众号,也可以加我的微SEO靠我

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2