streambuf类streambuf类提供物理设备的接口,它提供缓冲或处理流的通用方法,几乎不需要任何格式。缓冲区由一个字符序列和两个指 针组成,这两个指针是输入缓冲区指针和输出缓冲区指针,它们分别指向字符要被插入或取出的位置。streambuf类提供对缓冲区的低 级操作,如设置缓冲区、对缓冲区指针进行操作、从缓冲区取字符、向缓冲区存储字符。它有三个派生类,即filebuf、strstream buf和conbuf,其成员函数大多采用内置函数方式定义,以提高效率。filebuf类使用文件来保存缓冲区中的字符序列。当读文 件时,实际是将指定文件中的内容读到缓冲区中来;当写文件时,实际是将缓冲区的字符写到指定的文件中。strstreambuf类扩展 了streambuf类的功能,它提供了在内存中进行提取和插入操作的缓冲区管理。conbuf类扩展了streambuf类的功能, 用于处理输出。它提供了控制光标、设置颜色、定义活动窗口、清屏等功能,为输出操作提供缓冲区管理。streambuf类图ios类 ios类是一个虚基类,它主要定义了用于格式化输入输出及出错处理的成员函数。在ios类和它的各级派生类中,均含有一个指向流缓冲类st reambuf的对象的指针。ios类(及其派生类)使用streambuf类以及从它派生的文件缓冲类filebuf和字符串缓冲 类strstreambuf进行输入输出。ios流类列表ios流类和它的派生类的结构关系格式化I/O在很多情况下,程序员需 要控制输入输出格式。C++提供了两种格式控制方法:一种方法是使用ios类中有关格式控制的成员函数;另一种方法是使用称为控制符 的特殊类型的函数。格式状态字c++可以给每个流对象的输入输出进行格式控制,以满足程序员对输入输出格式的需求。输入输出格式由 一个longint类型的格式状态字确定,状态字的各位都控制一定的输入输出特征,例如格式状态字的最右一位为1,则表示在输入时跳过空 白符号。在ios类的public部分定义了一个枚举,它的每个成员可以分别定义格式状态字的一个位,每一个位称为一个状态标志位。 枚举定义enum{skipws =0x0001,left =0x0002,right =0x0004,i nternal =0x0008,dec =0x0010, oct =0x0020,hex =0x0040, showbase =0x0080,showpoint =0x0100, uppercase =0x0200,showpos =0x0400, scientific =0x0800,fixed =0x1 000,unitbuf =0x2000,stdio = 0x4000};枚举类型中定义的值用于设置或清除格式化输入输出中的控制信息的标志(1)skipws设置该标志 后,当从一个流中输入时,将跳过开头的空白字符(包括空格、制表符及换行符);否则不忽略空白字符。缺省为设置。(2)left、rig ht、internal在一次输出中,这三个标志只能设置其中的一个。如果设置1eft,则输出左对齐,域宽的其余部分用填充符填充; 如果设置right,则输出右对齐;如果设置internal,则数值的符号左对齐,而数值本身右对齐,符号和数值之间为填充符。(3) dec、oct、hex这三个标志也只能设置其中的一个。如果设置dec标志,则数值以十进制形式输入输出;如果设置oct标志,则 以八进制形式输入输出,如果设置hex,则以十六进制形式输入输出。缺省为dec。(4)showbase设置该标志后,数值数据的 前面要显示“基指示符”。例如,假定设置了标志hex和showbase,则在输出数值数据时,前面都要显示前缀“0x”。缺省为不设置。 (5)showpoint设置该标志后,强制显示float和double型数据的小数点及小数点后的无效0。缺省为不设置。(6 )uppercase如果设置该标志,则数值中的字母(如指数符号“e”、十六进制数字等)均以大写字母显示。缺省为不设置。(7) showpos设置该标志后,当显示正数时,前面加上一个正号“+”。缺省为不设置。(8)scientific、fixed 如果设置了scientific,则浮点数用科学记数法输出;如果设置了fixed,则浮点数按常规显示。如果二者都不设置,则编译程序根 据情况选用一种合适的方式。(9)unitbuf设置该标志后,在输出操作后立即刷新所有流,刷新一个流意味着把输出写到与流相连 的物理设备上。(10)stdio如果设置该标志,则每次输出后,刷新stdout和stderr输入输出格式的成员函数lo ngios::flags();//返回当前格式状态字longios::flags(long): //设置格式状态字并返回longios::setf(long);//设置指定的标志位longios::u nsetf(long);//清除指定的标志位intios::width();//返回当前显示数据的 域宽intios::width(int);//设置当前显示数据域宽并返回原域宽charios::fill ();//返回当前填充字符charios::fill(char);//设置填充字符并返回原填 充字符intios::precision();//返回当前浮点数的精度intios::precision( int);//设置浮点数精度并返回原精度用setf()函数设置格式状态时,可以包含两个或多个格式标志,由于这些格式标志 在ios类中被定义为枚举值,每一个格式标志以一个二进制位代表,因此可以用位运算符“|”组合多个格式标志。例如cout.setf (ios::hex|ios::showbase);使用I/O操纵符进行格式控制(1)定义在iostream头文件中的操纵符有: endl输出时插入换行符并刷新流ends输出时在字符串后插入空字符(NULL)作为尾符flush刷 新,把流从缓冲区输出到目标设备ws输入时略去空白字符dec以十进制形式输入或输出整型数hex 以十六进制形式输入或输出整型数oct以八进制形式输入或输出整型数使用I/O操纵符进行格式控制(2)定义在ioma nip头文件中的操纵符有:setbase(intn)设置转换基数为n(n取值为0、8、10或16),缺省时为0 ,表示采用十进制形式输出resetiosflags(longf)清除由参数f指定的标志位,用于输入输出setios flags(longf)设置参数f指定的标志位setfill(charc)设置填充字符setp recision(intn)设置浮点数精度(缺省为6)setw(intn)设置数据宽度文件 流C++把文件看作是字符(字节)的序列,即由一个一个字符(字节)的数据顺序组成。根据数据的组织形式,可分为ASCII文件和二 进制文件。ASCII文件也称文本(text)文件,它的每个字节存放一个ASCII代码,代表一个字符。二进制文件则是把内存中 的数据按其在内存中的存储形式原样输出到磁盘上存放。文件流在C++中,为了进行文件操作,必须首先建立一个文件流,然后把这个流和实 际的文件相关联,这称为打开文件;文件打开后,可以按要求进行读写操作,一般来说,在主存与外设的数据传输中,由主存到外设叫做输出或写 ,而由外设到主存叫做输入或读;完成输入输出后,还必须将已打开的文件关闭,即取消文件和流的关联。 文件的打开文件 使用时,必须先打开,后使用ifstreamin;//输入ofstreamout;//输出fstr eamboth;//输入和输出文件的打开有两种方式,一种是用输入输出流的成员函数打开,另一种是用构造函数打开。 用open函数打开文件用流ifstream、ofstream和fstream类对象的成员函数方式打开文件。open()函数是这 三个流类的成员函数,其原型为:voidopen(constunsignedchar,intmode,in taccess=filebuf::openprot);其中第一个参数用来传递文件名,第二个参数mode的值决定文件的打开方式, 第三个参数决定文件的保护方式,用户通常只使用缺省值。用构造函数打开文件用构造函数打开文件的格式是:ifstream对象名 ("文件名")ofstream对象名("文件名")fstream对象名("文件名",打开方式)只有在打开文件之后,才 能对文件进行读写操作。如果由于某些原因打不开文件(即执行函数open()失败),则流变量的值将为0。ifstreamfin( "mytest.txt");//打开输入文件if(!fin){ cout<<”Cannotopenfile! \n”; //错误处理代码}为了确保文件操作的顺利进行,在打开文件时通常都要判断是否成功打开方式打开方式是已经 在ios类中定义了的枚举常量。常用的有:ios::in打开一个文件用于输入(读)操作。ios::out 打开一个文件用于输出(写)操作ios::ate打开一个已有的文件,文件指针指向文件尾。ios::app 以输出方式打开文件,写入的数据添加在文件末尾ios::trunc打开一个文件。如果文件已存在,则删除其中全部数据;如 果文件不存在,则建立新文件。如果已指定了ios::out,而未指定ios::app、ios::ate、ios::in,则同时默认此 方式。ios::nocreate打开一个已有的文件,如果文件不存在,则打开文件失败(即不创建一个新文件)。ios::nor eplace如果文件不存在则建立新文件,如果文件存在,则打开失败。noreplace是不更新原有文件的意思。ios::bin ary指定文件以二进制方式打开,而不是缺省说明的文本方式。文件的关闭当对一个打开的文件操作完毕后,应及时调用文件流的成 员函数来关闭相应的文件。具体格式为:流对象名.close();其中流对象名为待关闭的文件流的对象名。close()函数不带任 何参数,也不返回任何值。文本文件的读写用流输出运算符“<<”和流输入运算符“>>”输入输出标准类型的数据用文件流的put、 get和getline等成员函数进行字符的输入输出.ignore()忽略若干字符ignore(1000,''\n'')最多抛掉 多少,到什么字符为止,如果没有第二个参数,就到文件尾,或到最多字符数。经常用来清空缓冲区.putback()退回一个字符. peek()查看下一个要读取的字符cin.clear();可以请除错误状态,不会请空缓冲区。I/O对象一旦处于错误状态, 就拒绝读写。eof()是否结束fail()是否失败bad()是否坏了good()是否好二进制文 件的读写二进制文件不是以ASCII代码存放数据的,它将内存中数据存储形式不加转换地传送到磁盘文件,因此它又称为内存数据的映像文件 。对二进制文件的读写主要用istream类的成员函数read和ostream类的成员函数write来实现的。这两个函数的原型如下 :istream&read(charbuffer,intlen);ostream&write(constchar buffer,intlen);文件的随机读写为了进行随机存取,必须先确定文件指针的位置。在C++中,可以用以下几个函数来确 定指文件指针位置。seekg(pos,orgin);seekp(pos,orgin);origin的取值有以下三种情况:i os::beg从文件头开始ios::cur从当前位置开始ios::end从文件尾开始tellg() tellp()这两个函数用来返回文件指针的当前位置异常处理异常在程序遇到一个无法处理的问题时,一个函数可以:终止程序 返回一个表示错误的值返回一个值,并让程序处于非法状态调用一个预先准备好在出现问题时用的函数抛出异常throw的作用是导致 堆栈的一系统回退。直到找到一个适当的catch.函数声明异常:throw(异常类型),throw()代表不抛出任何异常,不声明 代表可能抛出任何异常。为什么不写不代表不抛出异常呢?如果一个异常未捕获,就会导致调用std::terminate()函数处 理异常异常的多态和捕获所有异常 处理异常的顺序catch(...)异常对象与临时对象有一些区别,它会一直保留直到处理, 所以,catch一个异常对象是很正常的,并且我们经常使用引用。异常的重新抛出直接throw会重新抛出原先异常由于异常导致的堆 栈回退,申请的一些资源会自动调用析构造函数,所以程序出现异常时,对象的析构函数会释放资源。构造和析构构造函数中出现异常,如果 已经申请到的堆内存可能不能释放。解决的办法是不要要构造函数中调用过多会出现异常的函数或使用auto_ptr.构造函数中出现无法处 理的问题时可以抛出异常以告知调用者。析构函数的调用时机:1、正常调用2、异常中堆栈回退,异常处理机制退出一个作用域,其中包 含的析构函数会调用。如果析构函数中抛出异常,将会非常麻烦。在函数虚函数覆盖时的异常描述子类函数必须至少是父娄函数的异常描述一样 受限(显式的或隐式的)classB{public: virtualvoidf(); virtualvoidg() throw(X,Y); virtualvoidh()throw(X);};classD:publicB{ voidf()throw(X);//ok voidg()throw(X);//ok比父类更受限 voidh( )throw(X,Y);//error}; 标准库异常标准库异常由语言抛出:bad_alloc(new抛出)b ad_cast(dynamic_cast)bad_typeid(typeid)标准库异常:exception异常:标准库的根 异常在头文件中定义。logic_error异常,exceptoin子异常runtime_error exceptoin子异常自定义异常系统设计的开始阶段,就要把异常处理策略加入系统,在系统实现后再包含有效的异常处理是 非常困难的异常处理提供一个单独的、统一的处理问题的技术,这有助于在一个大的项目中的程序员互相了解各自的错误处理代码应避免利用异 常处理作为控制流程序的替代模式异常处理能够简化软件的各部分的组合,通过预定义的组件将问题传递给特定的程序组件,从而使它有效在工作 在一起当没有异常发生时,异常处理代码会造成很少甚至没有性能损失。因此,实现异常处理的程序运行起来比将错误处理代码和程序逻辑混合起 来的程序更高效。TheEnd拷贝构造函数类会提供默认的拷贝构造函数默认的拷贝构造函数会完成所有成员的逐个复制拷贝 构造的调用时机:函数值传递时函数返回时用同类型的对象初始时何时需要自定义拷贝构造函数?类中有指针(或引用)成员时希望 自定义对象的拷贝过程时使用匿名对象简化编程静态成员静态成员变量的初始化需要在类外完成静态成员不属于具体的某个对象,而属于整 个类所有对象共享本类中的静态成员静态成员最好直接通过类名::成员来访问和调用静态成员函数中没有this指针运算符重载 输入和输出cout<<对象被编译器解释为:cout.operator<<(对象)或operator<<(co ut,对象)cin>>对象被编译器解释为cin.operator>>(对象)或operator>>(ci n,对象)友元函数将函数声明成友元,以获得额外的权利friend一个成员函数的三项事情:1)访问类中的私用部分2) 函数位于类的作用域中3)必须经由对象调用(拥有this指针)一个静态成员函数只有前两种性质,而友员函数只拥有第一个性质。双目 运算符重载+、-、、/…<、>、>=、<=、==、!=…….使用成员函数实现使用友元函数实现注意事项重载 函数的参数尽量使用const尽量使用const函数实现重载单目运算符重载~、!、-++前++和后++--前- -和后--不允许被用户重载的运算符:: 作用域解析. 成员选择. 通过到成员的指针做成员选择?: 三目运算符 sizeoftypeid另外,不允许对基本数据类型进行运算符重载不能创造运算符也不能违反语法定义的形式,比如,不能将%重 载为一元运算只能定义为成员函数的运算符=、+=、-=、=、/=……[]下标运算()括号运算函数对象类型 转换->间接隐式类型转换和explicit利用构造函数可以实现隐式类型转换利用()运算符函数可以实现类型转换防止无意 之中的隐式类型转换classArray{explicitArray(int=10);}new和delete可 以重载new重载new时,必须重载delete重载new[]和delete[]封装、继承、多态封装private和pu blic给外界公开访问接口,隐藏具体的实现继承继承是软件复用的一种方式,通过继承,可以吸收现有类的数据和行为来创建新类,并 增添新的性能增加此类。软件利用能够节省软件开发时间,鼓励人们复用经过认可、调试的高质量软件,使用系统的开发更有效。基类和派生类 (父类和子类)是一个(isa)和有一个(hasa)是一个表示继承有一个表示组成继承的三种类型public继承p rotected继承private继承派生类对基类成员的访问权限基类成员的访问说明符继承类型Public继承Prote cted继承Private继承Public在派生类为public可以直接由任何成员函数、友元函数和非成员函数访问在派生类 中为protected可以直接由成员函数、友元函数访问在派生类中为private可以直接由成员函数、友元函数访问Prote cted在派生类中为protected可以直接由任何成员函数、友元函数访问在派生类中为protected可以直接由任何成员 函数、友元函数访问在派生类中为private可以直接由任何成员函数、友元函数访问private在派生类中隐藏可以通过基类 的public或protected成员函数由成员函数和友元函数访问在派生类中隐藏可以通过基类的public或protected 成员函数由成员函数和友元函数访问在派生类中隐藏可以通过基类的public或protected成员函数由成员函数和友元函数访问 继承中构造和析构的调用子类隐式地调用父类的构造函数有时,我们必需显式调用父类的构造函数子类名(参数列表):父类名(参数列表) ;析构函数会按照构造函数相反的顺序调用子类不会继承父类的构造函数、析构函数和赋值运算符函数。但是子类的这些函数可以调用父类的这 些函数继承中的成员函数名字隐藏静态成员函数的继承问题静态函数可以被继承到子类子类中定义了同名的,父类中的将会被隐藏当 私有继承时,成员函数的调用多重继承构造函数总是先调用父类的构造再执行自身的代码。多个父类按继承顺序执行构造。析构也会进行 相反的调用。多重继承的成员冲突及解决将冲突的成员抽象到更高层的类中,并且为了让这个类只构造一个,采用虚继承,即在public前 加关键字virtual,以保证这个类的对象在多个继承类中只保留一份。虚继承中的基类(虚基类)的构造参数由底层子类直接传递多态 多态指多种形态,是允许将父对象设置成为和一个或多个它的子类对象相等的技术多态性使得能够利用同一类(基类)类型的指针来引用不同类 的对象,以及根据所引用对象的不同,以不同的方式执行相同的操作在C++中,多态性体现为允许父类指针(或引用)来指向(或引用)子类对 象,当通过父类指针(或引用)调用函数时,实际调用的函数为子类对象的类型函数。从而实现对于同样的函数调用,每个对象会做出自己恰当的响 应把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化多态性使 我们能够进行“通用性编程”,多态性使编写的程序在处理同一个类层次结构下类的对象时就好像它们是基类的对象一样。虚函数C++中的多 态是由虚函数实现的。虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数 的一般形式: virtual函数返回值类型虚函数名(形参表){函数体}虚函数的作用是实现动态绑定,也就是在程序的运行 阶段动态地选择合适的成员函数在定义了虚函数后,可以在基类的派生类中对虚函数重新定义在派生类中重新定义的函数应与虚函数具有相同的 形参个数和形参类型。以实现统一的接口,不同定义过程。virtual函数经常需要子类做重写才能表现出多态来一个函数声明成virt ual函数,那么从整个继承层次的那一点开始起向下的所有类中,安将保持是virtual,即使子类重写了此函数而并没有显式地将其声明成 virtual函数的重写函数名相同参数列表相同返回类型相同静态绑定和动态绑定通过指向子类对象的父类指针或引用调用vi rtual函数时,程序会根据所指对象而不是指针指针类型,动态选择正确的子类函数。这种执行时选择合适的调用函数称为动态绑定或延迟绑定 当virtual通过对象名使用圆点运算符调用函数时,调用哪个函数是在编译期已经决定了的(称为静态绑定),此时的调用行为没没有多态 性。当然,如果基类中的函数不是虚函数,那么也没有多态性换句话说,C++中的多态是可选择的纯虚函数和抽象类永远不需要实例化的 类应该定义为抽象类一个虚函数不需要或不能写出任何实现时,可以定义为纯虚函数virtualvoidf()=0;存在纯虚函数 的类是抽象的抽象类为类层次中各种类定义提供公共的接口抽象类的纯虚函数必须在子类中重写,否则子类也是抽象类抽象类不能实例化 抽象类除不能实例化之外,其他功能和类完全相同动态绑定的底层实现—虚函数表vtable每个类中的虚函数会记录在该类的vtab le表中每次调用virtual函数时,程序都会利用vtable做出正确的选择C++通过vtable和动态绑定实现的多态性非常高 效,对性能的影响很小在一些对性能要求非常高的实时程序中,多态性的开销可能难以接受类型信息和类型转换使用dynamic_c ast来转换指针类型在运行时检查一个父类对象是否是子类对象:dynamic_cast<子类>(父类对象地址)如果成功,返回子 类对象地址,否则返回NULL。执行的前提是,父类中必须有虚函数。运算符typeid#typeid(类型 ),typeid(对象)返回type_info对象的引用name()返回类型名==!=是否同一种类型virt ual析构函数当通过父类指针delete一个子类对象时,构造的行为未定义在父类的析构函数前加virual,使用之成为虚析构函数 父类的析构函数在子类的析构函数执行之后执行如果一个类中有virtual函数,那么该类就应该提供一个virual析构函数。输 入输出流I/O输入/输出输入输出是程序的一个重要组成部分,程序运行所需要的数据往往要从外设(如键盘、磁盘等)得到,程序的运 行结果通常也要输出到外设(如显示器、打印机、磁盘等)中去。C++系统提供了一个用于输入输出操作的类体系,这个类体系提供了对预定 义类型进行输入输出操作的能力,程序员也可以利用这个类体系进行自定义类型的输入输出操作。C++中的标准输入输出cout显 示器,有缓冲,可重定向C++中的格式输入输出是自动进行的,不同类型的处理是通过运算符重载实现。cerr显示器,无缓冲,不 可重定向clog显示器,标准要求有缓冲,不要重定向,但一般实现如同cerr输出缓冲遇到换行、有输入、flush、满、 程序结束时自动刷新cinC++的流输入和输出是数据传送的过程,数据如流水从一处流向另一处。C++形象地将此过程称为流(st ream)。C++的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一个对象。流表示了信息从源 到目的端的流动。在输入操作时,字节流从输入设备(如键盘、磁盘)流向内存,称为输入流;在输出操作时,字节流从内存流向输出设备 (如显示器、打印机、磁盘等),称为输出流。流中的内容可以是ASCII字符、二进制形式的数据、图形图像、数字音频视频或其它形式的 信息。I/O流的缓冲区在内存中为每一个数据流开辟一个内存缓冲区,用来存放流中的数据。当用cout和插入运算符“<<”向显 示器输出数据时,先将这些数据送到程序中的输出缓冲区保存,直到缓冲区满了或遇到endl,就将缓冲区中的全部数据送到显示器显示出来。 在输入时,从键盘输入的数据先放在键盘的缓冲区中,当按回车键时,键盘缓冲区中的数据输入到程序中的输入缓冲区,形成cin流,然后用提 取运算符“>>”从输入缓冲区中提取数据送给程序中的有关变量。流类(streamclass)C++的I/O流类库是用继承方法建 立起来的一个输入输出类库,它具有两个平行类:即streambuf类和ios类,这两个类是基本类,所有的流类都可以由它们派生出来。 streambuf类ios类C++内部学习教程C++简介80年代初由贝尔实验室的BjarneStroustrup 设计和实现1983年被正式命名为C++1998年ANSI/ISO制定了C++国际标准2003年推出了修定版本C++一直在发 展变化中…C++和CC++包含整个C,C是建立C++的基础C++是强类型语言,对类型检查严格C++比C更丰富支持面向对象 支持泛型编程支持异常运算符重载等第一个C++程序/thefirstC++program/#include usingnamespacestd;//mainfunctionintmain(){ cou t<<"Helloworld!"<am.\n";}第一个C++程序和第一个C程序的不同可以选用g++编译器源文件扩展名可以是.cpp.cc.C.c xx等不再使用c中的头文件如果要用,可以在c头文件名前加c#include不再使用scanf/prin tf而是cin/cout标准的C++头文件不再以.h结尾在C++中要使用命名空间命名空间也称名字空间,即namespac e名字空间是一种描述逻辑分组的机制,如果一些声明按照某种准则在逻辑上属于同一集团,就可以将它们放入同一个名字空间,以表明这个事实 。防止命名冲突也是一个很重要的原因。一个人写的程序放到一个名字空间中也是一种可取的做法。使用某个名字空间下的对象或函数:n amespace-name::member-name::为域运算符,在此表名一种限定,一个范围定义命名空间一个名字空间 的成员必须采用如下的记法形式引入:namespacenamespace-name{//声明和定义}我们不能在名字空间定义 之外用加限定的语法形式为名字空间引入新成员新成员的声明和定义是可以分开的声明和定义分开后,编译器可以帮助捕捉到例如拼写或类型不 匹配一类的错误。一个名字空间也是一个作用域,一个程序越大,通过名字空间去描述其中逻辑上独立的各个部分也就越重要。理想情况是,程 序里的每个实体都属于某个可以识别的逻辑单位(模块),所以,一个非凡的程序里的每个声明都应该位于某个名字空间里,以此指明它在程序中所 扮演的角色。使用命名空间带限定词的名字。如果使用另外一个名字空间中的成员,需要加限定词,如:std::in使用声 明:usingstd::in使用指令:usingnamespacestd;无名名字空间无名名字空间中的成员可以直接使 用::访问C++中的结构、联合和枚举C中的结构、联合和枚举类型名包含struct,union,enum,而C++则不C++ 的结构中可以有函数,称为成员函数C++的匿名联合union{intx;charc[4];};x=100;C+ +的枚举不再是普通的整数类型,而是一种独立的类型,这个体现了C++强类型的特征C++的布尔类型boolc99的bool是一种宏 定义,而在c++中则是专门的一种数据类型boolbool的值一般为true(逻辑真)和false(逻辑假)和c一样,bool值 本质上也是整数,true等于1,false等于0 isLeap=true; intdays=28+isLeap; //2月份的天数另外,可以将任何值赋值给bool类型的变量以下4个值为false:0‘\0’NULL false其他一切值如果赋值给bool类型的变量都视为trueboolb=1;b=true;b=3.14 ;b=“abcdef”C++运算符转换C++中的运算符,可以用其他关键字转换x>0&&y>0可以写成x>0an dy>0下图为可以转换的列表C++中的函数函数的参数表严格匹配,空参代表没有任何参数,void形参依然可以使用不再支持C 语言中的隐式声明方式,函数调用前必需先声明或定义函数的返回类型int不能省略函数可以重载在同一作用域中,函数名相同,参数列表 不同的函数可以存在若干个,其返回值任意当出现重载函数时,使用函数指针显得有点问题,当给函数指针赋值时,指针的类型代表着具体的函数 。函数重载的实现是基于函数名的编译时改变当程序跨越编译器或由其它语言调用重载函数时,函数名在编译时编译器不能对其改变,否则无法 调用extern“C”可以告诉编译器,像C语言那样进行编译处理。函数参数的哑元和默认值函数的参数支持哑元哑元是一 种没有参数名的参数,主要是为了函数间的区别以及向前兼容函数的参数可以指定默认值,当调用时没有传参,就以默认值进行函数调用。有默 认值的形参必须靠右,声明和定义分开时,默认值必需在声明中指定,定义中不再指定。C++中的内联函数宏在C++中不提倡使用宏存 在着一些潜在的危险C++中的面向对象不允许预处理器访问类的成员数据。也意味着宏函数不能用作类的成员函数。内联函数保持了函数的所 有特点,但在需要的地方会像宏一样展开,不需要调用函数的开销。类中直接定义的函数自动被处理成内联函数,所以一般把内联函数放在头文件 中。inline是一种请求,实现方式取决于编译器,特别是当函数较大或是递归的时候。C++的内存分配new/deletei ntp2=newint;//不保证是零intp3=newint(100);intp4=newin t[5];deletep2;deletep3;delete[]p4;定位分配charbuf[100]={}; new(buf)int[25];不存在定位分配所对应的delete运算,一旦buf释放,new所分配的空间也随即释放C++ 的引用reference引用是另外一个变量的别名引用的声明intiVal;int&iRef=iVal;引用 必须初始化,且必须用变量初始化。不能写:int&a=10可以写成constint&a=10;//常量引用不可能 有空引用,必须确保引用和一块合法的存储单元关联当一个引用被初始化为指向一个对象,它就不能改变为指向另一个对象引用是用指针来实现 的在函数参数和返回值上的引用函数的形参可以是引用类型通过引用传递参数,称之为引用传递用const来保护引用参数的传递尽 量使用引用传递参数尽量使用引用代替指针永远不要返回对局部变量的引用,除非局部变量是静态的或是在动态内存中分配的C++中的类 型转换运算符static_cast<类型>()转换时做静态检查,即在编译时进行void到其他指针的转换reinterpr ect_cast<类型>()允许强转任何类型的指针把整数强转成指针,指针强转成整数const_cast<类型>()去掉cv 限制dynamic_case<类型>()动态转换成员指针成员指针是一种相对地址结构体中的成员(包括变量和函数)的相对地 址获取方式&结构类型名::成员声明成员指针变量成员类型结构类型名::指针变量名通过成员指针访问结构成员结构变量.指 针变量名结构地址->指针变量名C++之父给C程序员的建议在C++中几乎不需要用宏用const或enum定义明显的 常量,用inline避免函数调用的额外开销,用模板去刻画一族函数或类型,用namespace去避免命名冲突不要在你需要变量之前去 声明,以保证你能立即对它进行初始化。不要用malloc,new运算会做的更好避免使用void、指针算术、联合和强制,大多数情 况下,强制都是设计错误的指示器。尽量少用数组和C风格的字符串,标准库中的string和vector可以简化程序更加重要的是,试 着将程序考虑为一组由类和对象表示的相互作用的概念,而不是一堆数据结构和一些可以拨弄的二进制面向对象编程面向对象编程万物皆对 象程序就是一组对象,对象之间通过发送消息互相通知做什么每一个对象都有它自己的由其他对象构成的存储区每一个对象有一个类型一个 特定类型的所有对象都能接收相同的消息类类是用户定义的数据类型在类中声明的变量和函数称为类的成员变量称为数据成员(也叫成员变 量)函数称为成员函数(有时称为方法)可以用类来声明变量(也称为实例)。每个实例是类的一个对象定义类的实例可以称为类的实例化 定义类用struct定义类成员默认为公开用class定义类成员默认为私有类中成员的作用域privateprotectedpublic构造并使用对象定义类Time并使用成员变量时分秒成员函数显示滴答…使用标准库中的类string构造对象=+=+>>=<<===!=size()length()find()str[i]s.c_str(转换成c风格,返回char)其他成员函数构造函数构造函数和类名相同没有返回值类型只在建立对象的时候被自动调用一次调用构造函数的主要目的是初始化对象一个对象的创建过程:分配内存空间初始化成员变量,如果成员是对象,构造他调用构造函数默认的空参构造函数构造函数的使用构造函数重载构造函数也是函数,拥有重载的特征重载的构造函数在构造对象时根据参数自动选择利用参数默认值简化构造函数构造函数也拥有函数参数默认值的特性使用默认值可以减少构造函数的个数构造函数的初始化列表初始化列表可以让构造函数在调用之前进行初始化工作如果类的成员变量是const或引用类型,使用初始化列表是不二选择实践中,类的声明和定义是分开的请试着将写的类分成头文件和实现两部分调用对象的成员函数与this指针一个对象占多大空间呢?成员函数保存在哪儿?调用成员函数时,会自动传this指针this指针是指向当前对象的指针在成员函数中,可以将this指针当参数传递,也可以返回this指针,或返回通过this指针拿到的对象const对象和const成员函数成员函数可以声明成const函数(声明后加const)对于const对象,只能调用const成员函数Const函数和非const函数可以形成重载对于非const对象的函数调用优先选择非const成员函数对于类中的mutable数据成员,可以被const成员函数修改析构函数与类名同,但名称前有一个~一个类只有一个析构析构没有参数,没有返回值在一个对象释放前调用。释放可能是主动的,也可能是被动的。一个对象的析构函数只调用一次,但语法上允许多次调用默认析构函数何时需要自定义析构呢?堆中构造和释放对象new/delete构造和释放对象使用C风格分配空间构造对象malloc/freenew和malloc的不同new在分配空间后会比malloc多做三件事如果对象成员又是对象,自动构造此对象自动调用构造函数自动处理类型转换delete和free的区别delete在释放对象之前会调用析构函数 |
|