1. I/O流的常用控制符
dec 置基数为10
hex 置基数为16
oct 置基数为8
setfill(c) 设填充字符为C
setprecision(n) 设显示小数精度为n位
setw(n) 设域宽为N个字符
setiosflags(ios::fixed) 固定的符点显示
setiosflags(ios::scientific)指数表示
setiosflags(ios::left) 左对齐
setiosflags(ios::right) 右对齐
setiosflags(ios::skipws) 忽略前导空白
setiosflags(ios::uppercase) 16进制数大写输出
setiosflags(ios::lowercase) 6进制数小写输出
setiosflags(ios::showpoint) 显示小数点
setiosflags(ios::showpos) 正数前面加上正号
2.头文件:*iostream.h* *iomanip.h* *stdlib.h*
cout/cin 流的控制符 exit(0)
3.指针的几种类型:
int (*p)();p为指向函数的指针变量,该函数带回一个整形值
int *p();p为带回一个指针的函数,该指针指向整形数据
int (**)[n]p为一个指向一个指针变量的指针变量,被指向的指针变量指向一个含n个整形数据的一维数组
4.构造函数和析构函数特点及其区别:
a.构造函数可以有任意个形参,还可以重载(多个参数个数不同的函数);但析构函数不能有形参,因为是系统自动调用的.
b.构造函数不可以任意调用,只准系统调用;而析构函数不仅系统调用,也可以任意调用.
5.构造函数和析构函数什么时候自动运行?(例61)
构造函数:一般在定义类对象时自动运行.
析构函数:如果一个函数中定义了一个对象,则在这个函数运行结束时就执行一次;
当一个对象是使用NEW运算符被动态创建的,在使用DELETE运算符释放它时,DELETE将会自动调用析构函数.
拷贝初始化构造函数:当用tpoint N(M);语句时调用一次;
当对象作为实参向形参传递时,即对形参初始化时执行一次;
当遇到M=return(N);语句,即对M进行初始化时调用一次;
6.this 指针用法:例63中,当程序执行语句list elem(i);时,系统对this指针进行了如下的缺省赋值:this=&list;
赋值成员函数举例(此例在例63基础上):
void Assign(linear_list&);//说明语句;
void linear_list::Assign(linear_list&p)
{if(&p==this)
return;
nmax=p.nmax;
nelem=p.nelem;
list=new int[nmax];
for(int i=0;i<nmax;i++)
list[i]=p.list[i];
}
7.const,volatile对象和const,volatile成员函数
格式:const person per/volatile person per;
int func(int) const;/char func(int) volatile;
说明:1.普通对象既可以访问const对象,又可以访问volatile对象;
2.const对象只能访问用const修饰的成员函数;
volatile对象只能访问用其所长volatile修饰的成员函数;
3.也可以同时说明为const volatile对象或const volatile成员函数;
const volatile对象只能访问const volatile成员函数;
const/volatile对象也能访问const volatile成员函数;
8.不同继承方式的基类和派生类特性
------------------------------------------------
继承方式 | 基类特性 | 派生类特性
------------------------------------------------
| public | public
公有继承 | protected | protected
| private | 不可访问
------------------------------------------------
| public | private
私有继承 | protected | private
| private | 不可访问
------------------------------------------------
| public | protected
保护继承 | protected | protected
| private | 不可访问
------------------------------------------------
A:帮助理解:1)对于公有继承方式:
a.基类成员对其对象的可见性:公有成员可见,其他不可见。这里保护成员同于私有成员。
b.基类成员对派生类的可见性:公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员。
c.基类成员对派生类对象的可见性:公有成员可见,其他成员不可见。
所以,在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中的公有成员和保护成员。这里,一定要区分清楚派生类的对象和派生类中的成员函数对基类的访问是不同的。
2) 对于私有继承方式:
a.基类成员对其对象的可见性: 公有成员可见,其他不可见。
b.基类成员对派生类的可见性:公有成员和保护成员可见,而私有成员不可见
c.基类成员对派生类对象的可见性:所有成员都是不可见的。
所以,在私有继承时,基类的成员只能由直接派生类访问,而无法再往下继承。
3) 对于保护继承方式:
与私有继承方式相同,两者的区别仅在于对派生类的成员而言,对基类成员有不同的可见性。
B:帮助理解:1) 公有继承时,水平访问和垂直访问对基类中的公有成员不受限制。
2) 私有继承时,水平访问和垂直访问对基类中的公有成员也不能访问。
3) 保护继承时,对于垂直访问同于公有继承,对于水平访问同于私有继承。
4) 对于基类中的私有成员,只能被基类中的成员函数和友元函数访问,不能被其他的函数访问。
C:帮助理解:在公有继承时,派生类的成员函数可访问基类中的公有成员和保护成员;派生类的对象仅可访问基类中的公有成员。
9.派生类的构造函数和析构函数:
派构:
1.一般格式: 派生类名 (派生类构造函数总参数表):基类构造函数(参数表1),子对象名(参数表2)
{派生类中数据成员初始化};
2.调用顺序: a.基类的构造函数。b.子对象类的构造函数(如果有的话). c.派生类构造函数。
10.多继承:是指派生类具有多个基类。
多继承的构造函数:
《派生类名》(总参数表):《基类名1》(参数表1),《基类名2》(参数表2),...
{派生类构造函数体}
11.虚基类:如果基类被声明为虚基类,则重复继承的基类在派生磁对象实例中只好存储一个副本,否则,将出现多个基类成员副本。
虚基类说明格式如下: virtual<继承方式><基类名>
class B:virtual public A
注意:a.如果一个派生类有直接或间接的虚基类,那么派生类的构造函数的成员初始列表中必须列出对虚基类的调用,如果未被列出,则表示使用该基类的缺省构造函数来初始化派生类对象中的虚基类子对象。
b.虚基类的构造函数先于非虚基类的构造函数调用。
c.只有建立对象的那么个派生类的构造函数调用虚基类的构造函数,而该派生类的基类中所列出的对这个虚基类的构造函数的调用在执行中被忽略。
12.运算符重载:
operator 函数用法:(不能有下列字符:'::','.','*','->','? :')
1.一般:int class_name::operator <运算符> (形参列表) (例92)
2.增量减量运算符: (例93,94,95,96)
a.将一个增量运算符重载为前置的成员函数:
int class_name::operator++();
b.将一个增量运算符重载为后置的成员函数:
int class name::operator++(int);
c.将一个增量运算符重载为前置的友元函数:
int operator ++(class_name&);
d.将一个增量运算符重载为前置的友元函数:
int operator ++(class_name&,int);
e.下标运算符:
int class_name::operator[](形参) //只能是非静态成员函数
f.函数调用运算符:
int class_name::operator()(形参表)//只能是非静态函数,且不可以带有缺省的参数
g.成员选择运算符:
class_name $/* class_name::operator->();
h.new delete运算符:
void *class_name::operator new(siz_t,<arg_list>);
void *class_name::operator delete(void *,<size_t>);
new delete只能被重载为类的成员函数,不能是友元。而且无论是否使用关键字static
进行修饰,重载了的new和delete均为类的表态成员函数。
对于typedef unsigned size_t;
在头文件alloc.h,mem.h,stddef.h,stdio.h,stdlib.h均说明;
i.友元函数:
可以是一个类的非静态函数,也可以是类的友元函数。
{friend complex operator+(complex&,complex&);
};
以下五种运算符不说明成友元运算符:
"=","()","[]","->","type";
j.转换函数:
class_name::operator type(); //type 是任何一个合法的C++的类型名(包括基本数据类型和导出数据类型)以及由关键字const和volatile引出的表达示。)
//不带任何参数,也无返回值类型,总是返回type的值。只能是类的成员函数,不能说明为友元运算符。
k.类的赋值运算与运算符重载:
person & person::operator=(person &p)
{dele Name;
Name=new char[strlen(p.Name)+1];
strcpy(Name,p.Name);
Age=p.Age;
Sex=p.Sex;
return *this;
}
典型例题。当用系统自带对象赋值的函数,如果对象里有如 *Name
型的,则赋值后会使两个指针同时指向一个成员元素的地址,当调用析构函数释放时,会释放两次,多释放一次,而产生错误,这个典型例题是用于把一个成员元素
复制到另一个对象中,不是单纯移动指针,当调用析构函数时,会释放两次。
l.重载函数:系统仅对形参加以区别。
13.虚函数
一般情况下,指向一个对象的指针,不允许指向另一个对象,但指向基类对象的指针可以指向它的派生类,并可以访问派生类中原基类成员。
如果一个函数一旦说明为虚函数,则无论说明它的类被继承了多少层,在每一层中该函数都保持该virturl特性。且可以在派生类中对该函数省略virtual.
虚函数必须是类的一个成员函数,不能是友元,但它可以是另一个类的友元。虚函数不能是一个静态成员。
设定绑定方式,使程序具有灵活性,但执行效率低,占用内存多.
14.抽象类:纯虚函数
纯虚函数的一般形式为:virturl 类型名(参数表)=0;抽象类不能申请对象。
15.类属结构:
1.函数模板:template <class 模板形参表>
返回值类型 函数名(模板函数形参表)
{
函数体;
}
example:
template <class T>
void swap(T &.x,T&.y)
{T t;
t=x;x=y;y=t;
}
2.重载函数模板:调用用次序:
1)寻找一个完全匹配的函数,找到,调用之。
2)寻找一个函数模板,将其实例化产生一个匹配的模板函数,找到,调用之。
3)寻找重载函数中有无通过类型转换后产生参数匹配的函数,若有,调用之。
3.类模板:template <class 模板形参>
class 类模板名
{
类体;
}
example: tempplate <class T>
class stack
{private:
T *date;
int top;
public:
isempty();
}
template <class T>
{...}
16.类模板的友元:
a.一般的类模板友元函数。
b.封闭型的类模板友元函数。当用类型参数将类模板实例化为某个具体的模板类时,该类模板所包含的友元函数也将随之实例化。
c.开放型的类模板友元函数。
例一百二十一。
17.C++的I/O流库
1. I/O标准流类
-----------------------------------------
c++名字 | 设备 | C中的名字 | 默认的含义
-----------------------------------------
cin | 键盘 | stdin | 标准输入
-----------------------------------------
cout | 屏幕 | stdout | 标准输出
-----------------------------------------
cerr | 屏幕 | stderr | 标准错误
-----------------------------------------
clog | 打印机 | stdprn | 打印机
-----------------------------------------
2。键盘输入
cin>>a>>b>>c; //Ctrl+z终止
cin.get(char &ch)//从输入流获取一个字符,不忽略空格Ctrl+z终止
cout.put(ch)//输出一个字符
EOF//其值为-1,相当于终止符
cin.geline(char *buf,int limit,Deline='
')//buf为一个指针或数组,limit为字符个数,Deline为读取字符指定结束符。作用:从键盘读入一串字符。结束用Ctrl+z.
cin.gcount()//返回getline()刚刚读过的字符个数
cin.read(char *buf,int size)//读入指定数目的字符
cout.write(const char *str,int n)//cout.write("string",strlen("string");则输出全部字符。
cin.peek()//返回输入流的下一个字符,但是不提取它。
long(a)//a可以是指针地址,作用,强制转换为十进制数。
(void*)//ex:char str="abcde";cout<<str;将str为首地址字符串的首地址输出。
18.输入符,提取符重载:<< >>
例154 155例题
19.磁盘文件的输入。头文件#include"fstream.h" //例题从156开始
1.打开文件:
a. fstream outfile;
outfile.open("f1.txt",ios::out);//其中fstream为系统对文件专用操作类
b. ofstream ostream("f1.txt");
ofstream ostrm; ostrm.open("f1.txt");//表示打开某个写文件
c. ifstream istrm("f2.txt");
ifstream istrm; istrm.open("f2.txt");//表示打开某个读文件
-----------------------------------------------------------------------
方式名 | 用途
----------------------------------------------------------------------
in | 以输入方式打开文件
-----------------------------------------------------------------------
out | 以输出方式打开文件
-----------------------------------------------------------------------
app | 以输出追加方式打开文件
-----------------------------------------------------------------------
ate | 文件打开时,文件指针位于文件尾
-----------------------------------------------------------------------
trunc | 如果文件存在,将其长度截断为零,并清除所有内容,如果文件不存在,则创建新文件
-----------------------------------------------------------------------
binarg | 以二进制方式打开文件,缺省时为文本方式
-----------------------------------------------------------------------
nocreate |打开一个已有文件,如该文件不存在,则打开失败
-----------------------------------------------------------------------
noreplace |如果文件存在,除非设置 ios::ate或ios::app,否则打开失败
-----------------------------------------------------------------------
ios::in |ios::out |以读和写的方式打开文件
-----------------------------------------------------------------------
ios::out|ios::binary |以二进制方式打开文件
-----------------------------------------------------------------------
ios::in|ios::binary |以二进制方式打开文件
-----------------------------------------------------------------------
2. 关闭文件:
fstream outfile;
outfile.close();
3. 打开文件失败退出程序:用函数abort();退出,在头文件<stdlib.h"
4.判断文件结束函数.example: infile.eof()
5.getline(char*,sizeof(s));//读取一串字符
get()/put()//对文件字符操作,例如outfile.get
6.随机访问数据文件:
1)读指针
istream &istream::seekg(流中位置)//
istream &istream::seekg(偏移量,参照位置)//参照位置分为:cur=1/beg=0/end=2 input.seekg(-100,ios::cur);
streampos istream::tellg();//其中streampos定义为long型,它返回一个long型且值为当前指针离文件开头的位置(字节数)
2)写指针
ostream &ostream::seekp(流中的位置)
ostream &ostream::seekp(偏移量,参照位置)//参照位置同上
streampos ostream::tellp();
注意:读函数中有get(),写函数中有put(),操作读指针用seekg(),而写指针用seekp();write()和read()中的第一个参数必须为(char *),如果不是,一定要强制转换
7. while(!cin);//表示输入流有错。
cin.clear();//原型 void ios::clear(int=0);其用途是将错误状态的标志字中错误标志位清除,重新判断输入。
cin.ignor(80,ch);//如果ch='
',一般表示忽略一行,重新到下一行去输入
istream &istream::ignore(int n=1,int t=EOF);//跳过输入流中指定数量的字符的函数,t为终止符,一般EOF相当于<ctrl+z>操作
istream &istream::pubback(char ch)//退回一个字符到输入流的函数,其中ch是指出要退回输入流的字符。
20. 格式化输入和输出: 例题从 167开始
A.设置流的格式化标志
1).控制格式的标志位
------------------------------------------------------------------------------
标志位 | 值 | 含义 |输入/输出
------------------------------------------------------------------------------
skipws | 0x0001 | 跳过输入中的空白符 | i
------------------------------------------------------------------------------
left | 0x0002 | 输出数据左对齐 | o
------------------------------------------------------------------------------
rignt | 0x0004 | 输出数据右对齐 | o
------------------------------------------------------------------------------
internal | 0x0008 | 数据的符号左对齐,数据本身右对齐,之间为填充符 | o
------------------------------------------------------------------------------
dec | 0x0010 | 转换基数为十进制形式 | i/o
------------------------------------------------------------------------------
oct | 0x0020 | 转换基数为八进制形式 | i/o
------------------------------------------------------------------------------
hex | 0x0040 | 转换基数为十六进制形式 | i/o
------------------------------------------------------------------------------
showbase | 0x0080 | 输出数据前有0/0x | o
------------------------------------------------------------------------------
showpoint | 0x0100 | 浮点数输出带有小数点 | o
------------------------------------------------------------------------------
uppercase | 0x0200 | 用大写字母输出十六进制数值 | o
------------------------------------------------------------------------------
showpos | 0x0400 | 正数前面有“+”号 | o
------------------------------------------------------------------------------
scientfic | 0x0800 | 浮点数输出采用科学表示法 | o
------------------------------------------------------------------------------
fixed | 0x1000 | 使用定点数形式表示浮点数 | o
------------------------------------------------------------------------------
unitbuf | 0x2000 | 完成输入操作后立即刷新流的缓冲区 | o
------------------------------------------------------------------------------
stdio | 0x4000 | 完成输入操作后刷新系统的stdout | o
------------------------------------------------------------------------------
2).使用成员函数设置标志字:
1.long flags() //该函数用来返回标志字
2.long flags(long) //该函数使用参数更新标志字,返回更新前的标志字
3.long setf(long setbits,long field)//将field所指定的标志清零,将setbits为1的位置1,返回以前的标志字
4.long setf(long) //设置参数所指定的那些标志的位,返回更新前的标志字
5.long unsetf(long)//该函数用来清除参数所指定的那些标志位的位,返回更新前的标志字
在ios类中,定义了下面的表态类对象;
static const long basefield; //其值为dec/oct/hex
static const long adjustfield //其值为left/right/internal
static const long floatfield //其值为scientific/fixed
example: cin.setf(ios::dec,ios::basefield
B.格式输出函数:
1).设置输出数据所占宽度的函数
1.int width()//该函数返回当前输出数据的宽度
2.int width(int)//刻函数用来设置当前输出数据的宽度为参数值,并返回更新前的宽度值
2).填充当前宽度内的填充字符函数
1.char fill()//该函数用来返回当前所使用的填充字符
2.char fill(char)//该函数用来设置填充字符为参数值所表示的字符,并返回更新前的填充字符
3).设置浮点数输出精度函数
1.int precision()//该函数返回当前浮点数的有效数字的个数
2.int precision(int)//该函数设置浮点数输出时的有效数字个数,并返回更新前的值。
注意:float型实数最多提供7位有效数字,double型褛最多提供15位有效数字,long。。。提供19位有效数字
C.操作子:为了简化操作,提供了一系列操作子,操作子实际上是对象
--------------------------------------------------------------------
dec | 数值数据采用十进制表示 | i/o
--------------------------------------------------------------------
hex | 数值数据采用十六进制表示 | i/o
--------------------------------------------------------------------
oct | 数值数据采用八进制表示 | i/o
--------------------------------------------------------------------
setbase(int)| 设置数据转换基数为n(n为0,8,10,16),其中0表示缺省基数 | i/o
--------------------------------------------------------------------
ws | 提取空白符 | i
--------------------------------------------------------------------
ends | 插入空白符 | o
--------------------------------------------------------------------
flush | 刷新与流相关联的缓冲区 | o
--------------------------------------------------------------------
resetiosflags(long) | 清除参数所指定的标志位 | i/o
--------------------------------------------------------------------
setiosflags(long) | 设置参数所指定的标志位 | i/o
--------------------------------------------------------------------
setfill(int) | 设置填充字符 | o
--------------------------------------------------------------------
setsprecision(int) | 设置浮点数输出的有效数字个数 | o
--------------------------------------------------------------------
setw(int) | 设置输出数据项的域宽 | o
--------------------------------------------------------------------
21. 字符串流:例170开始
c++提供了两个类:头文件#include"strstrea.h"
1.ostrstream:其是从ostream派生来的,将不同类型转换为字符串,并存放到数组中.
ostrstream::ostrstream();//缺省构造函数,它用来建立存储所插入的数据的数组对象;
ostrstream::ostrstream(char *s,int n,int
mode=ios::out);//此构造函数中S是字符指针或字符数组,N是用来指定这个数组最多能存放的字符个数.mode参数给出流式的方式,缺省
为out方式,还可选用ate和app方式.
ostrstream类还提供了如下的成员函数:
int ostrstream::pcount();//返回流中已插入的字符个数;
char *ostrstream::str(); //返回标志字符串的数组的指针值;
2.istrstream:其是从istream派生来的,将文本项转换为变量所需要的内部格式.
istrstream::istrstream(char *s);//构造函数中S是一个字符指针或字符数组,使用该串来初始化要创建的流对象
istrstream::istrstream(char *s,int n);//此构造函数是使用串中前N个字符来构造串对象
22.异常处理
try{ }
throw 变量
catch(形式参数变量){ } //其中形数参数变量只能是一个,且类型不能像函数传递形参那样进行自动转换,必须完全批配
注意:1.当找不到指导配项时,就用黑认批配项abort()一终止程序
2.异常处理的数据类型是公有基类,抛掷异常的数据类型是派生类
3.异常处理的数据类型是指向公有基类的指针,抛掷异常的数据类型是指向派生类的指针
catch(基类)总能够捕获throw(派生类对象),所以catch(基类)块总是放在catch(派生类)块的后面,以避免catch(派生类)永远不能捕获异常