资源预览内容
第1页 / 共72页
第2页 / 共72页
第3页 / 共72页
第4页 / 共72页
第5页 / 共72页
第6页 / 共72页
第7页 / 共72页
第8页 / 共72页
第9页 / 共72页
第10页 / 共72页
亲,该文档总共72页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
面向对象程序设计( C+) 第6章 类与对象6.1 类的定义n类构成了实现C+面向对象程序设计的 基础,在C+语言面向对象程序设计中占 据着核心地位。它把数据和作用在这些数 据上的操作组合在一起,是封装的基本单 元。对象是类的实例,类定义了属于该类 的所有对象的共同特性。 n一个类是对一种概念的描述,或者说是对某一 类具体事物的抽象。nC语言中对“点”的描述:struct Point double x; double y;n上述描述说明了点由两个坐标组成这样的概念 。不过,它没有说明所描述概念的操作特性。 6.1.1 类的含义与表述nC+丰富了C语言的结构并称之为类,使其能够描述出 完整的概念。例如:struct Point double x; double y; void display( ) cout ”操作符。#include using namespace std; class Date public:int year, month, day; void print() cout d.yeard.monthd.day; /输入数据d.print();/显示日期cout 成员 的方式 ,只不过在类内,若是直接访问成员的方 式,实际就是 this-成员 的方式。n访问成员函数的形式为: 对象.成员函数() ;n或 指向对象的指针成员函数();n实际上,还需要另一个参数,作为this的实参 ,格式为:对象.成员函数(public:void set_int(int intnum) anint=intnum; int get_int( ) return anint; ;void main( )INTEGER Anint, *Pint;Pint=Anint.set_int(120);coutget_int( );n实际上,系统将上述程序改造为:class INTEGER int anint; public: void set_int(INTEGER * const this,int intnum) this-anint=intnum;int get_int(INTEGER * const this) return this-anint; ;void main( )INTEGER Anint,* Pint; Pint= Anint.set_int( coutget_int(Pint); nthis指针是一个常指针,还可以使用 const说明符将this声明为指向常量的常指 针。nconst成员函数中this的类型是:const X * const thisnconst成员函数的特点是它不能修改this 所指的对象成员。class INTEGER int anint;public:int crease( )return +anint;int decrease( ) constreturn -anint; /错误 ;例n在类INTEDER中,成员函数decrease()的原型后 跟一个const , 它说明此时该函数的this的类型是:const INTEGER * const thisn由于const成员函数不能修改this所指的对象的成 员,因此在decrease()函数体中的语句 anint 试 图改变this指向的对象的成员anint,这是不允许的 。但在crease()中,修改anint是完全许可的。nthis指针主要用在运算苻重载、自引用等场合。6.3.6 类的模板函数方法n类方法也可以是一个函数模板。例如:class X public: template void print(T x) cout(10);a.print才是一个真正的方法名。 6.4 构造函数与对对象初始化 n通常,一个对象在生成时应该被初始化 ,它的属性不应是0或随机值。 n尝试下面的两种初始化方式: 1 Date d = 2007, 1, 2; 2 Date d;d.setDate(2007, 1, 2); 6.4.1 构造函数n解决对象初始化问题的方法是为类定义 一种特殊的方法:构造函数,语法形式为 :类名(参数列表);例如:class Date int year, month, day;public:Date(int y=2007, int m=1, int d=30) year = y; month = m;day = d; . ; n1. 构造函数的特殊性语法上,构造函数名与类名必须相同,且 不能有返回类型(也意味着无返回值),除 此之外与普通方法相同,如可以有参数列表 、可以重载和设置参数的缺省值等。构造函数在生成对象时由系统自动调用 。构造函数必须是公有的,否则系统也无法 在构造对象时调用它。 n2. 缺省的构造函数 在C+中,每个类必须有构造函数,否则 不能生成类对象。 n如果用户没有定义,则系统自动生成一个 构造函数,称为缺省构造函数。 n缺省构造函数没有任何参数,形式为:类 名( ); n需要特别注意的是,只要用户自己定义了 一个构造函数,无论有无参数,系统将不再提供 缺省构造函数。 n3. 构造函数的重载与对象定义 创建一个对象意味着一次构造函数调用,因此, 对象后面的实参数列表必须与某一个构造函数的形参 列表相对应,使得系统能找到对应的构造函数并调用 它,否则将产生找不到适当匹配的错误。见例P101特殊情况说明:构造函数只有一个参数,则下面两个对象定义语 句的作用相同nStudent s2(“Tom“);nStudent s2 = “Tom”; /初始化而非赋值无参构造函数定义对象时不能带有括号n Student s1(); n4. 单参数构造函数的类型转换作用 n一个类的单参数构造函数为由类类型到 其它类型的转换提供了依据。 void print(Student s) cout (J).getname();/调用Student(char) 注意 :只有包含一个参数的构造函数具有类型转换的功能, 且在有二义性时会产生错误。6.4.2 用构造函数生成对象n除了直接定义一个对象会导致系统调用 构造函数外,还存在着其它一些需要调用 构造函数的情况。 n1. 无名对象 n可以用直接指定一个构造函数的形式来定义无 名对象,如:Student(“Tom“);Student(); n无名对象主要有如下二种作用:作函数参数void fn(string s);fn(string(“Mary“); 初始化对象nstring s = string (“Mary“);nstring s = “Mary“;nstring s (“Mary“); 系统将根据无名对象的参数值直接调用构 造函数构造对象s,而不是先构造临时对象再 拷贝给s。 n2. 临时对象 n在一些特殊情况下,系统可能生成临时 对象。例如,有如下函数原型: Student getStudent(.) .return s; 若以下述方式调用函数:Student sx = getStudent( );系统在函数返回时要创建临时对象保存getStudent的返回 值,再用临时对象拷贝构造sx。在没有为类提供适当的拷贝 构造函数时应注意这些问题。 n3. 对象数组定义对象数组时,系统为每个数组元素对 象调用一次无参构造函数以构造这些元素。Student ss4; n以不同的构造方式初始化对象数组 利用临时对象Student ss4 = Student(), Student(“hello“), Student(J);在提供了单参数的构造函数时,也可以依赖构 造函数的类型转换作用实现数组初始化,如:Student sx6 = “C+“, “Basic“, C; Student sx6 = Student(“C+“), Student(“Basic“), Student(C); 传统的结构方式 如果类没有任何构造函数,C+仍允许用C语言的结构方 式为数组赋初值,如: class Point int x, y;public: void print() cout nstring类的主要属性是一个记录字符序列存储 区的指针,可称为str,类似Student类中的name 。常用的构造函数包括: string(const char *s=0);/用0结束的字符串s初始化 string(int n,char c); /用n个字符c初始化 string(string /拷贝构造string s1(“a string“), s2; /s2为不含任何字符的字符串 string s2(10, a);/s2的值是aaaaaaaaaan2. string类支持的主要运算 赋值运算=。关系运算。字符串加法(+和+=),也称字符串连 接。下标运算。 输入输出运算和using namespace std; #include using namespace std; int main( ) string s1(“a string“), s2; int pos;cin s2; /输入s2if(s2s1) s1 += s2;/字符串连接else s1 += “ no link“;pos = s1.find(“ing“, 0);/查找s1中有无字符串”ing”if(pos != -1)s1.erase(pos, 3); /如果有将其删除cout s1.insert(0, “modified:“);/在s1开头插入一个串并输出 6.8 其它类型构造技术n1. 用union定义共用体类型 union X char c2; int i; ;X a; a.i = 257;/二进制形式0000000100000001 cout (int)a.c0 , (int)a.c1;虽然代码中只是为a.i赋值,但a.i的存储空间也是数组a.c 的存储空间,故代码的输出是1,1。可见,使用共用体的 好处是可以很容易地将一个数据“拆开”成部分来使用 ,同时也可以节约存储空间。人们称共用体是一种节约 空间的类。 n2. 用struct或class定义位域类型 位域是一种可以按位使用存储空间的类。 如果某些属性是占用二进制位数很少的整数,可以在类定义 中指定这些属性占用的二进制位数,如: class Mixed unsigned a:1, b:1, c:2;/a、b、c分别占用1、1、2个二进制位int x;public:Mixed(unsigned a1, unsigned b1, unsigned c1, int x1):a(a1), b(b1), c(c1), x(x1) ;n3. 用typedef描述类型的别名 在处理一些难以描述的类型时,typedef几 乎是唯一的方法。例如,考虑下述变量定义 语句: int array20;/定义数组array char *cpoint;/定义指针变量cpoint double (*fpx)(double);/定义指向函数的指针变量fpx 可以将这些变量定义改造成类型定义: typedef int array20;/定义数组类型array typedef char *cpo
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号