第二章C++基本知识速成 第一章已经从总体概念及基本原则等方面对面向对象程序设计进行了简要的介绍,之后 我们将逐步推进,讨论面向对象编程(OOP)的实现。本章对C++语言的基本知识进行说明 分析,帮助初学者尽快学会使用C+语言进行面向对象程序设计。 本章目的 介绍C++的词法符号( token) 了解C++程序基本框架 总览C++数据类型 掌握C++运算符及表达式 了解C++常量、变量的表示和用法 掌握程序流程控制基本语句 2.1.1C++的面向对象特征 概括地讲,面向对象系统包含3个要素:对象、类和继承。能支持所有上述3个方面的 语言,被称为面向对象语言。从本质上讲,C++并不是一种完美的面向对象设计语言,而是 C语言的一个超集,与C兼容也是其成功的一个重要方面,因而C++也是一种混合语言,既 支持传统的面向过程程序设计,又支持面向对象程序设计,灵活性大。它继承了传统C语言 的优点,克服了其不足;又在面向对象特征及非面向对象特征这两个方面增加了新功能,使 得它既适用于结构化程序设计,又能满足面向对象程序设计的要求,符合广大程序设计逐步 更新其程序设计观念和方法的要求,因而很快流行起来 的面向对象特征和风格 (1)C++借助于把一个数据结构及其操作函数组合在一起,提供了类/对象的构造和封 装机制 定义一个类的一般形式是 class calss name ∥有成员部分(类外部的代码不能直接访问的部分) data and methods ∥包括成员变量和成员函数 protected ∥保护的成员部分 public ∥公用成员部分 data and methods ∥公有部分定义的变量和函数 在缺省关键词的情况下,类中所有项均为私有的。C++中的 struct和 union也和 class 一样能够定义一个类,所不同的是定义成员时,在缺省关键词的情况下所有成员均为公有的。 (2)提供对象的创建和删除,特别是使用了构造函数和析构函数来管理对象 构造函数是一个特殊的成员函数,其函数命名与类名同名,它指定了一个类的实例对 象的建立和初始化过程
第二章 C++基本知识速成 第一章已经从总体概念及基本原则等方面对面向对象程序设计进行了简要的介绍,之后 我们将逐步推进,讨论面向对象编程(OOP)的实现。本章对 C++语言的基本知识进行说明 分析,帮助初学者尽快学会使用 C++语言进行面向对象程序设计。 本章目的: .介绍 C++的词法符号(token) .了解 C++程序基本框架 .总览 C++数据类型 .掌握 C++运算符及表达式 .了解 C++常量、变量的表示和用法 .掌握程序流程控制基本语句 2.1.1 C++的面向对象特征 概括地讲,面向对象系统包含3个要素:对象、类和继承。能支持所有上述3个方面的 语言,被称为面向对象语言。从本质上讲,C++并不是一种完美的面向对象设计语言,而是 C语言的一个超集,与C兼容也是其成功的一个重要方面,因而C++也是一种混合语言,既 支持传统的面向过程程序设计,又支持面向对象程序设计,灵活性大。它继承了传统C语言 的优点,克服了其不足;又在面向对象特征及非面向对象特征这两个方面增加了新功能,使 得它既适用于结构化程序设计,又能满足面向对象程序设计的要求,符合广大程序设计逐步 更新其程序设计观念和方法的要求,因而很快流行起来。 C++的面向对象特征和风格: (1)C++借助于把一个数据结构及其操作函数组合在一起,提供了类/对象的构造和封 装机制。 定义一个类的一般形式是: class calss_name { private: //私有成员部分(类外部的代码不能直接访问的部分) data and methods //可包括成员变量和成员函数 protected: //保护的成员部分 data and methods public: //公用成员部分 data and methods //公有部分定义的变量和函数 }object_name_list; 在缺省关键词的情况下,类中所有项均为私有的。C++中的 struct 和 union 也和 class 一样能够定义一个类,所不同的是定义成员时,在缺省关键词的情况下所有成员均为公有的。 (2)提供对象的创建和删除,特别是使用了构造函数和析构函数来管理对象。 构造函数是一个特殊的成员函数,其函数命名与类名同名,它指定了一个类的实例对 象的建立和初始化过程
析构函数是用于释放内存和删除由构造函数创建的对象。 例:EX11CPP #include <iostream h ∥不同于C的 stdio h class class ablin myclasso oid showO myclass: myclass( cout<<""in constructor\n ∥ou:用于处理标准输出 它将输出流中的数据发送到标准输出设备(显示器)上 ∥<:将数据插入到输出流中。 ∥a的值由 myclass()自动初始化 ∥注意,构造函数是没有返回值的 void myclass showo cout<<a<<endl maino myclass ob;∥变量说明语句也是动作语句,调用了构造函数 ob. show) return 0 其中:COUT为标准输出流〈 (3)能够进行对象间的消息传递、操作调用,除了使用操作符、指针、表达式外,还有 指向自身的this等。 (4)支持继承机制,特别是提供了在一种通用的功能上进行具体化定义的方法,使用 基类和派生类,形成了十分方便的继承机制。 在C++中,一个派生类可以有多个基类,支持多重继承。说明一个类继承另一个类的形 式为 class派生类名:[ public/private/ protected基类名 ∥冒号是类属范围算符(双目)
析构函数是用于释放内存和删除由构造函数创建的对象。 例:EX1_1.CPP #include <iostream.h> //不同于 C 的 stdio.h class myclass { int a; public: myclass(); void show(); }; myclass::myclass() { cout<<”in constructor\n”; //cout:用于处理标准输出, //它将输出流中的数据发送到标准输出设备(显示器)上。 //<<:将数据插入到输出流中。 a=10; //a 的值由 myclass()自动初始化 } //注意,构造函数是没有返回值的 void myclass::show() { cout<<a<<endl; } main() { myclass ob ; //变量说明语句也是动作语句,调用了构造函数 ob.show(); return 0; } 其中:COUT 为标准输出流〈〈 (3)能够进行对象间的消息传递、操作调用,除了使用操作符、指针、表达式外,还有 指向自身的 this 等。 (4)支持继承机制,特别是提供了在一种通用的功能上进行具体化定义的方法,使用 基类和派生类,形成了十分方便的继承机制。 在 C++中,一个派生类可以有多个基类,支持多重继承。说明一个类继承另一个类的形 式为: class 派生类名:[public/private/protected] 基类名 { //冒号是类属范围算符(双目) . . . }
例:EXl2CPP class base Int x void setx(int n)(x=n void showxo( cout<<x<<,n, i class derived public base void sety(int n)y=n; 3 void showy O( cout<<y<<n, }; derived ob ob. setx(10) ob. sety (20) return O (5)具有灵活的处理动态连接功能,其方法是使用虚函数(在函数名前用关键字 virtual 进行标识),它只能在最高层的基类中定义 C++中函数名和运算符重载也是支持多态性的好方法。例如,下面重载构造函数提供了 便利的初始化对象 例:EX13CPP #include <iostream. h> public 两种构造函数重载,使对象oba初始化,而obb没有 myclass((x=0; i //no initializer myclass( int n)(x=n //initialize int getxofreturn x; i myclass oba( 10); //declare with initial value myclass obb l/declare without initializer cout<<”oba:”<< oba getx(<n
例:EX1_2.CPP class base { int x; public: void setx(int n){x=n;} void showx(){cout<<x<<”\n”;} }; class derived:public base { int y; public: void sety(int n){y=n;} void showy(){cout<<y<<”\n”;} }; main() { derived ob; ob.setx(10); ob.sety(20); ob.showx(); ob.showy(); return 0; } (5)具有灵活的处理动态连接功能,其方法是使用虚函数(在函数名前用关键字 virtual 进行标识),它只能在最高层的基类中定义。 C++中函数名和运算符重载也是支持多态性的好方法。例如,下面重载构造函数提供了 便利的初始化对象。 例:EX1_3.CPP #include <iostream.h> class myclass { int x; public: //两种构造函数重载,使对象 oba 初始化,而 obb 没有 myclass(){x=0;} //no initializer myclass(int n){x=n;} //initializer int getx(){return x;} }; main() { myclass oba(10); //declare with initial value myclass obb; //declare without initializer cout<<”oba:”<<oba.getx()<<”\n”;
cout<<obb<<obb getxo<<n return 0 C++程序由函数和对象类组成,类在整体上代表一组对象的特征,声明类的目的上为了 建立对象。对象是在运行时存在的实体(例),由类模板创建所需的对象时,一个特殊的成 员函数(构造函数)被自动执行,以初始化建立的对象 类代表由抽象分析所认识到的真实世界的概念对象,是语言中表达抽象的一个有力的工 具。 2.1.2C+语言对C语言在非面向对象方面的增强 C++除了继承传统C语言中的精华,并增加了许多的面向对象方面的特征之外,还在非 面向对象方面对C语言进行了增强 1、++提供了单行注释方式 传统的C语言中提供了块注释方式,其形式如下: /explanation setence 而在C++中,除保留块注释外,还增加了一种更方便的单行注释方式,其形式如下: //explanation sentence 2、更为灵活的变量说明 传统的C语言中,局部变量的说明必须放在可执行代码的前面。数据说明语句和可执 行语句的混合将引起编译错误。而在C++中,可以在程序代码块的任何地方进行局部变量的 说明,所说明变量的作用域是从对该变量进行说明的地方到该变量所在的最小分程序的未 尾 结构、联合和枚举名可直接作为类型名使用 在C语言中,在对结构、联合和枚举类型进行定义后,要生成该结构、联合和枚举类 型的变量,必须使用如下形式: struct struct name obj name union union name obj name emunmun name obj name 即必须在说明的结构、联合和枚举名的前面加上说明其所属类型的标识符。而在C++ 中,在对结构、联合和枚举类型进行定义后,该结构、联合和枚举名便可作为类型名使用, 可以直接用它进行对象定义。 4、枚举类型与整数关系 在C语言中,枚举值与整数值之间可以相互转换使用。而C++的类型检査则比C要严 格,枚举值将被自动转化为整型值使用,但将整型值转化为枚举值则需要进行强制类型转换, 否则会出现编译错误。如下面的一段代码,在C语言中都是可以接受的,但某些语句在C++ 中则会引起错误 mun name (John, Mike, Rose Joan mun name personl=John;
cout<<”obb”<<obb.getx()<<”\n”; return 0; } C++程序由函数和对象类组成,类在整体上代表一组对象的特征,声明类的目的上为了 建立对象。对象是在运行时存在的实体(例),由类模板创建所需的对象时,一个特殊的成 员函数(构造函数)被自动执行,以初始化建立的对象。 类代表由抽象分析所认识到的真实世界的概念对象,是语言中表达抽象的一个有力的工 具。 2.1.2 C++语言对 C 语言在非面向对象方面的增强 C++除了继承传统 C 语言中的精华,并增加了许多的面向对象方面的特征之外,还在非 面向对象方面对 C 语言进行了增强。 1、 ++提供了单行注释方式 传统的 C 语言中提供了块注释方式,其形式如下: /*explanation setence */ 而在 C++中,除保留块注释外,还增加了一种更方便的单行注释方式,其形式如下: //explanation sentence 2、更为灵活的变量说明 传统的 C 语言中,局部变量的说明必须放在可执行代码的前面。数据说明语句和可执 行语句的混合将引起编译错误。而在 C++中,可以在程序代码块的任何地方进行局部变量的 说明,所说明变量的作用域是从对该变量进行说明的地方到该变量所在的最小分程序的未 尾。 3、结构、联合和枚举名可直接作为类型名使用 在 C 语言中,在对结构、联合和枚举类型进行定义后,要生成该结构、联合和枚举类 型的变量,必须使用如下形式: struct struct_name obj_name; union union_name obj_name; emun emun_name obj_name; 即必须在说明的结构、联合和枚举名的前面加上说明其所属类型的标识符。而在 C++ 中,在对结构、联合和枚举类型进行定义后,该结构、联合和枚举名便可作为类型名使用, 可以直接用它进行对象定义。 4、枚举类型与整数关系 在 C 语言中,枚举值与整数值之间可以相互转换使用。而 C++的类型检查则比 C 要严 格,枚举值将被自动转化为整型值使用,但将整型值转化为枚举值则需要进行强制类型转换, 否则会出现编译错误。如下面的一段代码,在 C 语言中都是可以接受的,但某些语句在 C++ 中则会引起错误。 emun name {John,Mike,Rose,Joan}; emun name person1=John;
mun name person3=1 l/This is an error in C++ mun name person4=(emun name)l 5、C++增加了无名联合类型 无名联合是C++中提供的一种特殊联合,可以用来说明一组无标记名的、共享同一内 存地址的数据项。例如 union Int 1: float f 无名联合可以通过使用其中数据项名字直接进行访问。(?) 6、作用域限定运算符: 作用域限定运算符::用于对当前作用域之外的同名变量进行访问。如在下面的例子中, 在局部变量var的作用域内使用 来实现对全局变量var的访问 例:EX14CPP #include <iostream. h> Int var void maino float var ∥局部变量var var=6 ∥局变量var cout<< local variable var=”<<var<<n” cout<<globle variable var=<<:var<<"n 7、函数调用时的参数传递方式 在C语言中,函数调用时的参数传递是用按值传递方式进行的,在子函数中对形参的 改变并不引起实参的数值改变。而在C++中,函数调用时的参数传递是用按地址传递方式进 行的,形参和实参所指向的是同一内存区域的内容,因此在了函数中对形参的修改将会导致 实参的数值变化 8、增强了类型转换方式 在C++中,除保留了传统C语言的强制类型转换方式外,还可以将类型名作为函数名 使用,这将大大提高程序的可读性。例如 float f=0. 01 long k=long();∥将类型名作为函数名用 9、void类型 在C+中,、void类型指针是可以与任何类型指针相匹配的指针。Void类型指针可以被赋
emun name person2=person1; emun name person3=1; //This is an error in C++! emun name person4=(emun name)1; 5、C++增加了无名联合类型 无名联合是 C++中提供的一种特殊联合,可以用来说明一组无标记名的、共享同一内 存地址的数据项。例如: union { int i; float f; }; 无名联合可以通过使用其中数据项名字直接进行访问。(?) 6、作用域限定运算符:: 作用域限定运算符::用于对当前作用域之外的同名变量进行访问。如在下面的例子中, 在局部变量 var 的作用域内使用::var 来实现对全局变量 var 的访问。 例:EX1_4.CPP #include <iostream.h> int var; void main() { float var; var=3.14; //局部变量 var ::var=6; //全局变量 var cout<<”local variable var=”<<var<<”\n”; cout<<”globle variable var=”<<::var<<”\n”; } 7、函数调用时的参数传递方式 在 C 语言中,函数调用时的参数传递是用按值传递方式进行的,在子函数中对形参的 改变并不引起实参的数值改变。而在 C++中,函数调用时的参数传递是用按地址传递方式进 行的,形参和实参所指向的是同一内存区域的内容,因此在了函数中对形参的修改将会导致 实参的数值变化。 8、增强了类型转换方式 在 C++中,除保留了传统 C 语言的强制类型转换方式外,还可以将类型名作为函数名 使用,这将大大提高程序的可读性。例如: float f=0.01; long l=(long)f; long k=long(f); //将类型名作为函数名用 9、void 类型 在 C++中,void 类型指针是可以与任何类型指针相匹配的指针。Void 类型指针可以被赋