C++程序设计

1、C++程序设计基础

C++程序设计包括数据类型(基本内置类型、复合类型)、输入输出处理、语句、函数以及类

1.1数据类型

1.1.1基本数据类型
  1. C++是强类型编程语言,在继承C语言基本数据类型(char 、int、float、double、void)的基础上,C++扩展了布尔类型(bool)和宽字符类型(wchar_t)、Unicode字符类型char16_t和char32_t(使用char16_t和char32_t需要包含头文件uchar.h)。
  2. bool类型的数据的取值为真(true)或(false),wchart_t类型数据占用2个字节,char16_t和char32_t分别用两个字节和四个字节表示。
1.1.2常量和变量

在程序中,数据都具有类型,以常量和变量形式描述。

  1. 字面值常量
    ①布尔型字面常量为false和true;
    ②整型字面值默认是int类型,可以加后缀“u”或“U”表示无符号int型;加后缀“l”或“L”表示long型;加后缀“ll”或“LL”表示long long型;
    ③浮点型字面值默认类型为double类型,可以加后缀“f”或“F”表示float型;加后缀“l”或“L”表示long double型;
    ④字符型字面值用一对单引号括起来,字符串常量由一对双引号括起来;字符和字符串字面值加后缀“u”表示char16_t类型(Unicode16字符),加前缀“U”表示char32_t类(Unicode32字符),加前缀“L”表示wchar_t(宽字符),加前缀“u8”表示字符串字面值编码采用UTD-8(char类型,8位编码一个字符);

  2. 左值(Lvalue)和右值(Rvalue)
    ①左值的实质是内存位置,左值可以出现在赋值号的左边或者右边;变量即有左值(具有存储单元)也有右值(具有值),即字面量和常数右值。
    ②右值的实质是数值,右值可以出现在赋值号的右边,但不能出现在赋值号的左边;变量有左值,因此可以出现在赋值号的左边。数值型的字面值是右值,不能被赋值。

  3. 定义常量:可以用宏定义和const定义常量。例如:

#define  SZ    100
const  double   a=  12.0;

宏定义的本质是字符替换,没有数据类型的概念,const常量有类型,在编译阶段进行类型检查;宏替换在预处理阶段展开不能对宏定义进行调试,宏定义给出的常量在程序运行时位于代码段(或者说系统不为该常量不分配内存),const常量位于数据段(系统为常量分配内存,是只读数据)。

1.1.3复合数据类型
  1. C++的枚举、结构体、公用体、和数组都是复合数据类型,其定义和使用要求与C语言完全兼容,同时进行扩展,其中,结构体、共用体类型可作为类类型定义,通过标准库类型vector为用户提供灵活的数组。
1.1.4引用和指针
  1. 引用(Reference)为对象提供了另一个名字(别名),通过将声明符写成“&d”的形式来定义引用类型,其中“d”是声明的变量名;不同于变量的定义,引用必须在定义时初始化。;引用必须用对象进行初始化,用字面值或表达式初始化引用编译时编译会保存;引用提供了与指针相同的能力,但比指针更加直观,更易于理解“&”和“*”符号的作用与其所在位置相关
  2. 引用与指针不同:①不存在空引用。引用必须连接到一个合法的对象。②一旦引用被初始化为一个对象,就不能再引用另一个对象。指针可以指向另一个对象。③引用必须在创建时被初始化。指针可以不进行初始化。

1.2运算符、表达式和语句

①C++继承了C语言的算数运算符、关系运算符、逻辑运算符、位运算符、赋值运算符和其他运算符,扩充了“::”、new 、delete等运算,还支持对运算符的重载机制。
②表达式是描述运算的,由运算符作用的一个或多个运算对象来组成,对表达式求值得到一个结果,字面值和变量是最简单的表达式。
语句是描述控制的,表示分支(选择)结构的语句有if语句和switch语句,表示循环控制语句有while、do-while和for。
④C++11扩充了范围for语句,从而可以用简单的方式遍历容器或其他序列的所有元素。
⑤break语句用在switch语句中时,用于跳出switch语句,结束switch语句的执行。break语句在循环语句中的作用是终止并跳出循环。
⑥continue语句的功能与break不同,它是结束当前这一次的循环,转而执行下一次循环
⑦return语句用于将执行流程从函数中返回。

1.3基本输入/输出

①大多数C程序使用称为stdio的标准I/O库进行输入输出处理,该库也能够在C++中使用。但是,C++程序主要使用称为iostream的I/O流库②在C++中,流是输入/输出设备的另一个名字,如一个文件、屏幕、键盘等。每个I/O设备传送和接受一系列的字节,称为输入操作:可以看成字节从一个设备流入内存。输出操作:可以看成字节从内存流出到一个设备。使用C++的标准I/O流库时,必须包括以下两个头文件:#include<iostream>#include<iomanip>iostream文件提供基本的输入/输出功能,iomanip文件提供格式化的功能。通过包含iostream流库,内存就可以创建一些用于处理输入和输出操作的对象。标准的输出流(通常是屏幕)称为cout,标准的输入流(通常是键盘)称为cin

  1. 输出:输出内置类型的数据到标准的输出设备,用“<<”运算符和cout输出流。例如,输出变量a的值到输出设备的语法:cout<<a,以上语句表示传送a的值到标准的输出设备(由cout表示)。另一种方法是a作为函数参数调用函数operator<<。cout.operator<<(a)由于cout.operator<<(d)写起比较繁琐,因此常写成cout<<d。需要换行时用cout<<endl。符号endl的功能是换行,并清除输入缓冲区。
  2. 输入:标准输入的用法与标准输出类似,使用**“>>”**运算符和cin输入流。例如cin>>d从标准输入读一个值存入变量d,并与语句中数据类型匹配。如果d是整型数,上面的命令读数字,直到遇到的不是数学为止;如果d是浮点数,该命令读数字、小数点、指数,直到没有遇到合适的字符为止。
  3. 格式控制:有两种方法设置数据的输出格式:直接设置输出流的格式状态通过输入/输出操作符。下面常用的两种:精度(Precision)、和宽度(Width)①精度:是指有效数字位数。②宽度:是指数据输出的总位数。一旦设置了精度,在下一次设置前,原设置值保持不变。宽度有所不同,他是数据输出的最小位数,如果宽度不够,则会分配更多的位数。也就是说,当width位数不够时,输出的数据不会被截断。而且输出操作完成后,width会恢复为默认值。还有一些标志可以设置浮点数数的固定表示或指数表示、输出值得对其方式(右、左或居中)、是否显示尾部0,这些标志用成员函数setf设置。例如,要使用标准输出,指数表示、左对齐及显示尾部0,可以使用下面语句:cout.setf(ios::left,ios::adjustfield); cout.setf(ios::showpoint,iso::showpoint); cout.setf(ios::scientific,ios::floatfield);

1.4函数

函数是一组语句,用来完成特定的任务。有两种函数,①一种是已经定义好并随编译系统发布的、可供用户调用的标准函数,也称为库函数;②另一种是用户根据需要自己定义的

1.4.1函数定义和声明
  1. 函数定义包括以下几个部分:函数名、参数列表、返回类型和函数体。函数声明的作用是告诉编译器函数名称及如何调用函数。
1.4.2函数调用
  1. 程序运行中进行函数调用时,程序的控制流转移到被调用函数。
  2. 调用函数时,传递所需参数。
  3. C++函数调用时有两种参数传递方式,既值传递和引用传递
    ①在值调用方式下,函数在被调用前,形参变量并不占内存单元,当函数被调用时,才为形参变量分配存储单元,并将相应的实参变量的值复制到形参变量单元中。所以,被调用函数在执行过程修改形参的值并不影响实参的值。
    ②在引用调用方式下,本质上是将实参的地址传给形参,在被调用函数中通过间接访问方式访问实参数据,简单来说,可将形参看作实参的别名,在被调用函数中对形参的访问实质上就是对实参的访问。
1.4.3内联函数
  1. ①定义函数时,在“返回类型 函数名(参数列表)”之前加上inline使之成为内联函数,即“inline 返回类型 函数名(参数列表)”。
  2. ②对于内联函数,编译器是将其函数体放在该调用内联函数的地方,不存在普通函数调用时栈记录的创建和释放开销。
  3. ③使用内联函数注意的问题:
    ⒈在一个文件中定义的内联函数不能在另一个文件中使用。他们通常放在头文件中进行共享。
    ⒉内联函数应该简介,只有几个语句,如果语句较多,不适合定义为内联函数。
    ⒊内联函数体中不能有循环语句、if语句或switch语句,否则函数定义时,即使有inline关键字,编译器也会把该函数作为非内联函数处理。
    ⒋内联函数要被函数调用之前要声明。
1.4.4 函数的重载
  1. ①C++中,当有一组函数完成相似功能时,函数名允许重复使用,编译器根据参数列表的个数或类型来判断调用那个函数,这就是重载。对于重载函数,只要其参数表中参数个数或类型不同,就视为不同函数。

  2. ②定义重载函数时,注意一下几个问题:
    ⒈避免函数名相同,但功能完全不同的情形。
    ⒉函数的形参变量名不同不能作为重载的依据
    ⒊C++中不允许函数名相同、形参个数和类型也相同而返回值不同的情

1.5类与对象

①对象是人们进行研究的任何事物,从最简单的整数到复杂的机器都可以看做一个对象。对象可以是具体的事物,也可以是抽象的规则、计划或事件。对象具有状态,一个对象用数据值来描述它的状态。对象具有操作,用于改变对象的状态,对象及其操作就是行为。
②具有相同或相似性质的对象的抽象就是。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象。类具有属性,它是对象的状态的抽象,用数据结构来描述类的属性。类具有的操作,他是对象行为的抽象,用操作名和实现该操作的方法来描述。

1.5.1类
  1. 类的定义由类头类体两部分组成。
  2. 类头:由class关键字开头,然后是类名,其命名规则与一般标识符命名规则一致。
  3. 类体:类体放在一对花括号中。
  4. 类的定义也是一个语句,所以要有分号结尾,否则会产生编译错误。
  5. 类体定义类成员:
    数据成员,它指定了该类对象内部的表示
    成员函数:他指定该类的操作
    类成员有3种不同的访问权限:
    ⒈公有(public):成员可以在类外访问
    ⒉私有(private):成员只能被该类的成员函数访问
    ⒊保护(protected):成员只能被该类的成员函数或派生类的成员函数访问。
    ④数据成员通常是私有的;成员函数通常有一部分是公有的,一部分是私有的。公有的成员函数可以在类外被访问,也称为类的接口。
    ⑤类的成员函数在类外定义,一般形式如下:
返回类型  类名::函数名(形参列表){
     函数体
}

双冒号“::”是域运算符,主要用于类成员函数的定义。
⑥在C++中,允许在结构体(Struct)和共用体(Union)中定义函数,他们也具有类的功能,与class不同的是,结构体和共同体的默认访问控制是public。一般情况下,应该用class来描述面向对象概念的类。

1.5.2对象

类是用户定义的数据类型(不占用内存单元),它存在于静态的程序中(即运行前的程序)。而动态的面向对象程序(即运行中的程序)则由对象构成,程序的执行是通过对象之间相互发送消息来实现的对象是类的实际(占内存单元)。

  1. 对象的创建:定义了类以后,就可以定义类类型的变量,类的变量称为对象。在所有函数之外定义的对象称为全局对象,在函数和局部对象定义的对象称为局部对象,在类中定义的对象称为成员对象。全局对象和局部对象的生存期和作用域的规定与普通变量相同。成员对象将随着包含它的对象的创建而创建、消亡而消亡,成员对象的作用域为它所在的类。通过new操作创建的对象称为动态对象,其存储空间在内存的堆区。动态对象用delete操作撤销。
  2. 对象的操作:对于创建的一个对象,需要通过调用对象类中定义的成员函数来对它进行操作,采用**“对象名.成员函数名(实参表)”或“指针对象的指针->成员函数名(实参表)”**的形式表示。
  3. 构造函数
    ①程序运行时创建的每个对象只在初始化后才能使用。对象的初始化包括初始化对象的数据成员以及对象申请的资源。对象消亡前,往往也需要执行一些操作,如归还对象占有的空间。
    ② C++中定义了一种特殊的初始化函数,称为构造函数。当对象被创建时,构造函数自动被调用。构造函数的名字与类名相同,它没有返回值和返回类型。当对象创建时,会自动调用构造函数进行初始化。
    休息:对构造函数的调用时对象创建过程的一部分,对象创建之后就不能再调用构造函数了。
    ④ 构造函数也可以进行重载,其中,不带参数(或所有参数都有默认值)的构造函数称为默认构造
    ⑤对于常量数据成员和引用数据成员(某些静态成员),不能在声明时进行初始化,也不能采用赋值对他们进行初始化。
    ⑥可以在定义构造函数时,在函数头和函数体之间加入一个数据成员进行初始化的来实现。
    ⑦如果类中有常量数据成员或引用数据成员,并且类中定义了构造函数,则一定要在定义的所有构造函数的成员初始化中对他们进行初始化
  4. 析构函数:当对象销毁时,会自动调用析构函数进行清理工作。析构函数也与类同名,但在名字前有一个“~”,析构函数也没有返回类型和返回值。析构函数不带参数,不重载。若一个对象中有指针数据成员,且该指针数据成员指向某个内存块,则在对象销毁前,往往通过析构函数释放该指针指向的内存块。对象的析构函数在对象销毁前被调用,对象何时销毁也与其作用域相关。例如,全局对象在在程序运行结束时销毁,自动对象是在离开其作用域时销毁,而动态对象则是使用delete 运算符时销毁。析构函数的调用顺序与构造函数调用顺序相反。当用户未显式定义构造函数和析构函数时,编译器会隐式定义一个内联的、公有的构成函数和析构函数。默认的构造函数执行创建一个对象所需要的一些初始化操作,但它并不涉及用户定义的数据成员或申请的内存的初始化。
1.5.3静态成员

有时,可能需要一个或多个公共的数据成员能够被类的所有对象共有。在C++中,可以定义静态(static)的数据成员和成员函数。要定义静态数据成员,只要在数据成员的定义前增加static 关键字。
静态数据成员不同于非静态的数据成员,一个类的静态数据成员仅创建和初始化化一次,且在程序开始执行的时候创建,然后被该类的所有对象共享,也就是说,静态数据成员不属于对象,而是属于类;而非静态的数据成员则随着对象的创建而多次创建和初始化。
C++也允许定义static 成员函数,与静态数据成员类似,静态成员函数也是属于类。在静态成员函数中,仅能访问静态的数据成员,不能访问非静态的数据成员,也不能调用非静态的成员函数。公有的、静态的成员函数在类外的调用方式为:类名::成员函数名(实参表)。

1.5.4this指针

C++中定义了一个this指针,用它来指向类的对象。this指针是一个隐含的指针,不能被显示声明。

  1. 每个成员函数都拥有一个this指针,this 是一个形参、一个局部变量,存在于类的非静态成员函数中(仅能在类的成员函数中访问),this 局部于某一个对象,它指向调用该函数的对象。
1.5.5友无

根据数据保护的要求,不能在一个类的外部访问该类的数据成员,C++用private 访问控制来保证这一点,对private 数据成员的访问通过提供的public 成员函数进行。
在C++的一个类中定义,可以指定某个全局函数、某个其他类或某个其他类的成员函数来直接访问该类的私我(private)和保护(protected)成员,它们分别称为友元函数、友元类和友元类函数,统称友元。
友元的作用是提高程序设计的灵活性,是数据保护和对数据的存取效率之间的一种折中方案。

2、继承与多态

2.1继承

  1. 代码复用是C++最重要的特点之一,它是通过类的继承机制实现的。通过类的继承,在程序中可以复用基类的代码,并可以在继承中增加新代码或覆盖被继承类(基类)的成员函数,为基类成员函数赋予新的意义,实现最大限度的代码复用。
  2. 派生类(子类)与基类(父类)是有一定联系的。基类:描述一个事物的一般特征。派生类:比基类更加丰富的属性和行为。如果需要,派生类可以继承多个基类,也就是多重继承。通过继承,派生类自动得到了除基类私我成员以外的其他说有数据成员和成员函数,在派生类中可以直接访问,从而实现代码的复用。
  3. 派生类对象生成时,要调用构造函数进行初始化,过程为:先调用基类的构造方法,对派生类中的基类数据进行初始化,然后再调用派生类自己的构造方法,对派生类的进行数据进行初始化。在派生类中也可以更改基类的数据,只要他有访问权限。
  4. 基类数据的初始化要通过基类的构造函数,而且他要在派生类数据之前初始化,说以基类构造函数在派生类构造函数的初始化调用。
  5. 访问说明符:**public、private、protected **控制数据成员和成员函数在类内类外如何访问。
    ①当一个类的成员定义为public ,就能够在类外访问,包括它的派生类;当一个成员定义为private ,他仅能在类访问,不能被它的派生类访问。
    ②当一个类成员定义为protected,它内在的类内和派生类内访问。
    ③当一个成员没有指名访问修饰符时,默认为private 。
    在定义派生类时,访问说名符也能出现在基类前面,它控制基类的数据成员和成员函数在派生类中的访问方法
    ①当访问说明符为public 时,基类的公有成员变为派生类的公有成员,基类的保护成员成为派生类的保护成员。
    ②当访问说明符为protected 时,基类的公有和保护成员均为派生类的保护成员
    ③当访问说明符为private 时,基类的公有和保护成员变为派生类的私有成员。

2.2多态

  1. 面向对象程序设计的核心是多态性,简单来说就是**“一个接口,多种方法”**,程序在运行时才决定所调用的函数。
  2. 在派生类中的可以定义与基类同名的函数,也就是说基类的成员函数提供了一个新的定义,在派生类中定义与基类中的定义有完全相同的方法的方法(即参数个数类型均相同)和返回类型,对于普通成员函数,这称为重置(或覆盖);而对于虚成员函数,则称为实现。
  3. 多态也称为动态绑定迟后绑定,因为到底调用那个函数,在编译时不能确定,而要推迟到运行时确定。也就是说,要等到程序运行时,确定了指针指向的对象的类型时才能够确定。
  4. 函数调用是通过相应的函数名来实现的。将源程序进行编译后并加载在内存执行,函数实际上是一段机器代码,它是通过首地址进行标识和调用的。在C++中,函数调用在程序运行之前就已经和函数体(函数的首地址)联系起来。编译器把函数体翻译成机器代码,并记录了函数的首地址。对函数调用的源程序进行编译时,编译器知道这个函数名的首地址在哪里(它可以从生成的标识符表中查到这个函数名对应的首地址),然后将这个首地址替换为函数名并一并翻译成机器码。这种编译方法称为早期绑定静态绑定
  5. 当用基类指针调用成员函数,是调用基类的成员函数还是调用派生类的成员函数,这由指针指向的对象的类型决定的。也就是说,如果基类指针指向基类对象,就调用基类的成员函数;如果基类指针指向派生类对象,就调用派生类的成员函数。这就要用到另一种方法,称为动态绑定迟后绑定
  6. 在C++中,动态绑定是通过虚函数来实现的。虚函数定义很简单,只要在成员函数原型前加一个关键字virtual。如果一个基类成员函数定义为虚函数,那么它所在的派生类中也保持虚函数,即使在派生类中省略了virtual 关键字。要达到动态绑定的效果,基类和派生类的对应函数不仅名字相同,而且返回类型、参数个数、和类型也必须相同。
  7. 仅定义了函数而没有函数实现的函数称为纯虚函数。定义纯虚函数的方法是在虚函数参数表右边的括号加一个“=0”的后缀。
  8. 含有纯虚函数的类,称为抽象类。C++不允许用抽象类创造对象,它只能被其他类继承。要定义抽象类,就必须定义纯虚函数,它实际上起到一个借口的作用。
  9. 对虚函数的限制是:只有类的成员函数才可以是虚函数;静态成员函数不能是虚函数;构成函数不能是虚函数,析构函数可以是虚函数,而且常常将析构函数定义为虚函数。

3、异常处理

  1. 异常(Exception)是程序可能检测到的运行时刻不正常的情况,如new无法取得所需的内存、除数为0、运算溢出、数组越界访问或函数参数无限,这样的异常存在于程序的正常函数功能之外,但是要求程序立即处理。C++提供了一些内置的语言特性来产生并处理异常,以提高程序的容错能力,气候程序更加健壮。异常机制使一个函数可以在发现自己无法处理的错误时抛出一个异常,希望其调用者可以直接或间接处理这个问题。

  2. 传统的错误处理技术在检查到一个局部无法处理的问题时,常用以下方式。
    ①终止程序
    ②返回一个表示错误的值
    ③返回一个合法值,让程序处于某种非法的状态
    ④调用一个预先准备好在出现的“错误”的情况下的函数
    第一种情况经常是不允许的,无条件终止程序的方式不适合应用到不能宕机的程序中。第二种情况比较常用,但有时会带来不便。第三种情况容易误导调用者,如果调用者没有去检查表示错误码的全局变量或者通过其他式检查错误,会造成无法预料的后果,这种方式在并发情况下不能很好的工作。第四种情况比较少,而且回调代码不应过错出现。

  3. C++的异常机制为程序提供了一种处理错误的方式,使程序员可以更加自然的方式处理错误。使用异常把错误和处理分开,由库函数抛出异常,由调用者捕获这个异常,调用者就可以知道程序函数库调用出现错误并加以处理。

  4. try、catch 、finally 和throw是异常处理的关键字,他们配合起来工作。try内一般放入程序或函数的工作代码(出错时发生异常的代码),catch 是程序发生异常后的出错处理程序,每个catch 块指定捕获和处理一种异常,而finally 块中则放着不论是否出错都需要处理的代码。throw 用来声明函数可以抛出的异常和程序检测到出错时用来抛出一个异常对象

  5. 如果一个函数抛出一个异常,它必须假定该异常能被捕获和处理。在函数内抛出一个异常(或函数调用时抛出异常)时,就退出函数执行。如果不希望在异常抛出时退出函数,可在函数内创建一个特殊用于解决实际程序的问题,由于可通过它测试各种函数的调用,所以被称为测试快,由关键字try引用。

  6. 函数的所有潜在异常类型随关键字throw 插入在函数声明中。

4、标准库

C++标准库可以分为标准函数库和类库两部分。标准函数库继承自C语言,是由通用的、独立的、不属于任何类的函数组成。面向对象类库是类及其相关函数的集合。
标准函数库:包含了所有的C标准库,有输入/输出、字符串和字符处理、数学运算、时间、日期和本地化、动态分配和其他处理,为了支持类型安全,做了一定的添加和修改。
面向对象类库:定义了支持一些常见操作的类,如I/O类、string 类、数值类和STL的容器类、算法、函数对象、迭代器、分配器,以及异常处理类。

4.1I/O流库

①C++语言没有设置内部的输入/输出功能,其目的是最大限度地保证语言与平台的无关性。在进行输入操作时,可以把输入数据看成逐个字节地从外设流入计算机内部;在进行输出操作时,则把输出的数据看成逐个字节从内存流到外设。
②C++使用iostream流进行输入/输出操作。iostream是一组C++类,可以提供无缓冲的和缓冲的I/O操作。
③C++国际标准将所有标准组件都放入了名字空间::std中,并且把I/O流库模块化。程序中使用流库时,#include〈iostream〉是符合C++国际标准;#include 〈iostream.h〉是各个编译器和库厂商保留用作向后兼容的遗留功能。

4.1.1抽象流基类
  1. ios为流基类
4.1.2输入流类
  1. istream:普通输入流类和用于其他输入流的基类
  2. ifstream:输入文件流类
  3. istream_withassign:用于cin的输入流类
  4. istrstream:输入串流类
4.1.3输出流类
  1. ostream:普通输出流类和用于其他输出流类的基类。
  2. ofstream:输出文件流类。
  3. ostrean_withassign:用于cout 、cerr、和clog的流类。
  4. ostrstream:输出串流类。
4.1.4输入/输出流类
  1. iostream:普通输入/输出流类和用于其他输入/输出流的基类
  2. fstream:输入/输出文件流类
  3. strstream:输入/输出串流类
  4. stdiostream:用于标准输入/输出文件的输入/输出类。
4.1.5缓冲流类
  1. streambuf:抽象缓冲类基类
  2. filebuf:用于磁盘文件的缓冲流类
  3. strstreambuf:用于串的缓冲流类
  4. stdiobuf:用于标准输入/输出文件的缓冲流类
4.1.6预定义流初始化类
  1. iostream_init为预定义流初始化类
4.1.7注意
  1. 其中,ios、istream、ostream和streambuf类构成了C++中iosstream输入/输出功能的基础。输出流类在iostream.h中预定义了4个全局的流对象:cout、cerr、clog、和cin,用于标准输出和输入,cout 、cin在程序中经常用到。
  2. cout 流对象控制向控制台(显示器)的标准输出,cin控制从控制台(键盘)输入。cerr与标准错误设备连在一起,是非缓冲输出,也就是说插入到cerr的数据会被立刻显示出来,非缓冲输出可以迅速把错误信息通知给用户。clog 也是与标准错误设备连在一起的,但它是缓冲输出。
  3. 可以利用无参的构造函数打开文件流,然后调用open()。
  4. 字节流可直接与内存而不是与文件或者标准输出一起工作。可以用于标准输出同样的格式操作内存里的数据(字节)。①如果想把数据放入字节流,可以建立一个osstrstream对象;②如果想从字节流中提取数据,流建立istream对象。istrstream类支持一个字符数组作为源的输入流。在构造istrstream对象前,必须存在一个字符数组,而且这个数组中已经填充了想要提取的字符。下面是两个构造函数原型。

4.2String

C++的字符串标准库类型是重新定义的类string,使用string时不必担心空间大小与字符串长短问题,其提供的操作函数足以完成大多数情况的需要。

4.2.1声明string对象

使用string 类型时必须包含头文件〈string 〉,然后可以像声明一个基本类型变量一样声明字符串变量。

4.2.2string 对象的操作

类string 提供了各种操作。

  1. 字符串的赋值和连接。string 的赋值可使用操作符“=”,其值可以是string 和c_string ,甚至是单一的字符,还可以使用成员函数assign()
  2. 删除字符串。删除字符串可以使用clear()和erase()
  3. 计算字符串长度。size ()和length ()可计算现有的字符数。empty()用来检查字符串是否为空。max_size()计算当前C++字符串最多能包含的字符数(最大长数)。capacity ()返回string 中包含的最大字符数。
  4. 访问串中的字符。可以使用下标操作符[]和函数at()对字符串包含的字符进行访问。但应该注意的是,操作符[]并不检查索性是否有效,如果索性失效,会引起未定义的行为。如果使用at()时索性无效,会抛出out_of_range异常。
  5. 求子串。substr方法的作用是提取子串
  6. 字符串比较。C++字符串支持常见的比较操作符,甚至支持string 与c_string 的比较。字符串按字典顺序从前向后逐一比较,字典排序靠前的字符小,遇到不相等的字符时,就按这个位置上两个字符比较结果确定两个字符串的大小。
    成员函数compare()支持多参数处理,支持用索引值和长度定位子串进行比较。比较结果用一个整数表示:0表示相等,正数表示大于,负数表示小于。

4.3STL(standard template library)标准模板库

STL是一系列软件代码的统称,其代码从广义上分为三类:算法(Algorithm )、容器(Container )和迭代器(Iterator),几乎所有的代码都采用了模板类和模板函数的设计方式,相比于传统的由函数和类组成的库,STL提供了更好的代码重用方式。在C++标准中,STL被组织为下面13个头文件**:〈algorithm〉、〈deque〉、〈functional〉、〈iterator〉、〈vector〉、〈list〉、〈map〉、〈memory〉、〈numeric〉、〈queue〉、〈set〉、〈stack〉、〈utility 〉**。

  1. 算法:STL提供了近百个实现算法的函数模板。例如,算法for_each将为指定序列中的每一个元素调用指定的函数,stable_sort以用户指定的规则对序列进行稳定排序。用户程序可以只通过调用STL中的算法来完成所需的功能,以提高开发效率,简化代码。
    算法部分主要由头文件〈algorithm 〉、〈numeric〉和〈function 〉说明。〈algorithm 〉是所有STL头文件中最大的一个,它是由大量模板函数组成的,可以认为每个函数在很大程度上都是独立的,其中常用到函数涉及比较、交换、查找、遍历、复制、移除、反转、排序和合并等操作。〈numeric〉只包括几个在序列上进行简单数学运算的模板函数,包括加法和乘法在序列上的一些操作。〈functio〉中定义了一些模板类,用于函数对象。

  2. 容器:容器是一种存储指定类型值的有限集合的数据结构,经典的数据结构数量有限,在实际的开发过程中,程序员经常为了实现向量、链表等结构而编写相似的代码,这些代码只是为了适应不同类型数据的变化而在细节上有所区别。STL容器允许重复利用已有的实现,来

实验一 C++简单程序设计(2学时) 1.编程计算图形的面积。程序可以计算圆形、长方形、正方形的面积、运行时先提示用户选择图形类型,然后,对圆形要求用户输入半径、对长方形要求用户输入长和宽的值,对正方形要求用户输入边长,计算出面积后将其显示出来。要求使用debug调试功能观察程序运行中变量值的变化情况。 2.定义一个表示时间的结构体,可以精确的表示年、月、日、小时、分、秒;提示用户输入年、月、日、小时、分、秒的值,然后完整地显示出来。 实验二 函数的应用(2学时) 1.编写重载函数Max1,分别求出两个整数,两个双精度数,三个整数,三个双精度数的最大值。 2.使用重载函数模板重新实现上面的函数Max1。 要求:(1)练习重载函数的使用;(2) 练习函数模板的使用。 实验三 类与对象(2学时) 1.声明一个Dog类,包含age、weight等属性,以及对这些属性操作的方法。实现并测试这个类。 2.设计并测试一个名为Rectangle的矩形类,其属性为矩形的左下角和右上角两个点的坐标,有成员函数能计算矩形的面积。 3.定义一个CPU类,包含等级、频率,电压等属性,并编写构造函数、析构函数,以及成员函数run、stop模拟CPU的状态。其中,等级为整型,频率为单位是兆赫兹的整数,电压为浮点型。要求自己设计各个属性的标识。 4.定义一个简单的Computer类,包含数据成员cpu、ram、cdrom等等,有两个成员函数run、stop。其中cpu为CPU类的一个对象,ram为RAM类的一个对象,cdrom为CDROM类的一个对象,定义并实现这个类。 5.(必做)设计一个用于人事管理的People类。考虑到通用性,可以只抽象出所有人员都 具有的属性:number(编号),sex(性别) ,birthday(出生日期),id(身份证号)等等。其中“出生日期”定义为一个“日期”类内嵌子对象。用成员函数实现对人员函数的录入和显示。要求包括:编写构造函数和析构函数、拷贝构造函数、内联成员函数,类的组合。 实验四 C++程序的结构(2学时) 1.编写程序,实现并测试客户机(Client)类。定义字符型静态数据成员ServerName[10],保存其服务器名称;整型静态数据成员ClientNum,记录定义的客户数量;定义静态函数ChangeServerName()改变服务器名称。在头文件client.h中定义类,在文件client.cpp中实现,在文件test.cpp中测试这个类,观察相应的成员变量的取值的变化情况。 2、在实验三题目5编写的人员类中设计适当的方法来实现类中数据的共享性,并采用多文件结构实现程序。 3.(选做)定义类X、Y、Z,函数h(X *),满足:类X有私有成员i,Y的成员函数g(X *)是X的友元函数,实现对X的成员i加1,类Z是类X的友元类,其成员函数f(X *)实现对X的成员i加5,函数h(X *)是X的友元函数,实现对X的成员i加10。在一个文件中声明类,在一个文件中实现类,在另一个文件中测试类。 实验五 继承和派生(2学时) 1.设计并定义一个交通工具类,并通过该类派生出新的类,编写程序定义这些类并测试它; 2.(选做)声明一个基类Shape,在此基础上派生Rectangle和Circle,二者都有GetArea()函数计算对象的面积,编写程序测试。 3.(选做)声明一个哺乳动物类Mammal,再由此派生出狗类Dog,定义一个Dog类的对象,观察基类与派生类的构造函数和析构函数的调用顺序。 4.完善实验四第2题的程序,具体要求如下: 任务1:从people(人员)类派生出student(学生)类,添加属性:学校、学院、专业、班号、入学成绩,设计相应的成员函数(构造函数,拷贝构造函数,录入函数,显示函数)。 任务2:从people类派生出teacher(教师)类,添加属性:职务,部门,职称。并设计相应的成员函数。 任务3:从student类派生出graduate(研究生)类,添加属性:导师,研究方向。并设计相应的成员函数。 任务4:编写程序来测试这个类。 实验六 小型学生管理系统的设计与实现1(2学时) 设计学生类、课程类、成绩类及相应的成员函数。要求能实现学生的信息、课程信息和成绩信息的增加、修改、删除与查询。 实验七 多态性(2学时) 1.定义Point类,有坐标X和Y两个成员变量,对Point类重载++和――运算符,实现对坐标值的改变。 2.定义一个车(Vehicle)类,有run,stop等成员函数,由此派生出自行车(bicycle)类、汽车(car)类,由bicycle类和car类派生出摩托车(motocar)类,它们都包含run,stop等成员函数,编写相应的虚函数并测试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值