1、2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程12022年8月9日3时13分面向对象程序设计与Visual C+6.0教程2类的定义与使用类的定义与使用 类的数据成员和成员函数类的数据成员和成员函数类成员的访问控制方法类成员的访问控制方法类的实现和对象的创建类的实现和对象的创建访问类成员的方法访问类成员的方法构造函数与析构函数构造函数与析构函数复制构造函数及深复制与浅复制复制构造函数及深复制与浅复制类作用域类作用域静态成员静态成员类的友元类的友元常对象常对象2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程3 类是对具有相同属性类是对具有相同
2、属性(数据数据)和行为和行为(操作操作)的一的一组对象的抽象。组对象的抽象。面向对象程序设计的核心任务是类的确定和对面向对象程序设计的核心任务是类的确定和对象的创建,而不是将各个具体的对象逐一进象的创建,而不是将各个具体的对象逐一进行描述。行描述。忽略各具体对象的非本质特征,抽象出本质特忽略各具体对象的非本质特征,抽象出本质特征与共性,然后形成类的概念,对象是类的征与共性,然后形成类的概念,对象是类的实例。实例。从语法分析,类也是一种数据类型,即用户从语法分析,类也是一种数据类型,即用户自定义的数据类型,而一个一个具体的对象自定义的数据类型,而一个一个具体的对象可以视为属于这一数据类型的一个变
3、量。可以视为属于这一数据类型的一个变量。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程4 类是对具有相同属性和行为的一组对象类是对具有相同属性和行为的一组对象的抽象与统一描述;的抽象与统一描述;类的定义包括行为和属性两个部分;类的定义包括行为和属性两个部分;属性以数据表示,行为通过函数实现。属性以数据表示,行为通过函数实现。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程5class 类名 public:公有数据成员和成员函数;protected:保护数据成员和成员函数;private:私有数据成员和成员函数;各成员函数的实现;2022年8
4、月9日3时13分面向对象程序设计与Visual C+6.0教程6 class Student /定义学生类定义学生类Studentpublic:/声明类成员声明类成员 void Getinfo(char*pname,char*pid,char Sex,int a,double s);void modify(float s);void display();private:char*name;char*id;char sex;int age;double score;/类定义以分号结束类定义以分号结束 2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程7 类的定义中不能对数
5、据成员进行初始化。公有部分是类对外的接口,一般应先说明公有部分 类的任何成员都必须指定访问属性,一般将数据成员定义为私有成员或保护成员,将成员函数定义为公有成员。类中的数据成员可以是C+语法规定的任意数据类型,但不能用存储类型auto、register或extern进行修饰。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程8 类的成员可以是其他类的对象,但不能以类自身的对象作为本类的成员,而类自身的指针和引用可以作为类的成员。类定义必须以分号“;”结束。在C语言中,结构体只有数据成员,而C+的结构体不仅有数据成员,而且有成员函数及访问权限控制。类与结构体的区别:没有明
6、确指定类成员的访问权限时,C+结构体的成员是公有的,而类的成员是私有的。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程9类的访问属性有:Public Protected Private 各种访问方式的功能如下表2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程10 访问控制含义属 性public公有成员类的外部接口protected保护成员仅允许本类成员函数及派生类成员函数访问private私有成员仅允许本类成员函数访问2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程11 类的成员函数是实现对封装的数据进行操作的惟一
7、途径,是现实类的行为属性的成员。一般将成员函数声明为函数原型,在类外具体实现成员函数。如果成员函数已经在类中定义,则无须在类外实现。类中定义的成员函数自动成为内联函数。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程12返回值类型 类名:成员函数名(参数表)函数体 2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程13 在类中实现的成员函数自动成为内联函数;内联成员函数可以减少函数调用开销,提高程序的执行效率;内联成员函数增加了程序代码的长度;一般将调用频繁且代码少的成员函数定义为内联成员函数;若内联成员函数在类外实现,需要以inline限定。
8、2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程14类描述了一类问题的共同属性和共同属性和行为行为,对象是类的实例或实体。类与对象的关系,如同C+基本数据类型和该类型的变量数据类型和该类型的变量之间的关系。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程15对象的定义格式如下:类名类名 对象名对象名1,对象名,对象名2,对象名,对象名n;2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程16 必须必须在定义了类之后,才可以定义类的对象;类定义仅提供该类的类型定义。仅仅定义了类,系统并不会分配存储空仅仅定义了类,系统并不
9、会分配存储空间,只有定义了对象后,编译系统才会在内间,只有定义了对象后,编译系统才会在内存中预留空间。存中预留空间。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程17 声明了类及其对象以后,就可以访问对象的公有成员(包括数据成员和成员函数)。对象成员的访问包括:圆点访问形式圆点访问形式 指针访问形式指针访问形式2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程18对象名对象名.公有成员公有成员2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程19形式一:形式一:对象指针变量名对象指针变量名-公有成员公有成员形式二:形式
10、二:(*对象指针变量名对象指针变量名).公有成员公有成员 2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程20l本章例4-7程序中出现了New运算符;lNew运算符用于动态内存分配,在后续章节中有专门介绍;lNew 运算符使用形式:l指针所指向的数据类型应与new 运算符后的数据类型相同,若申请成功则返回分配单元的首地址给指针变量,否则返回空指针值(即0)给指针变量。例如:(1)指针变量指针变量=new 数据类型;数据类型;(2)指针变量指针变量=new 数据类型数据类型(初始值初始值);(3)指针变量指针变量=new 数据类型数据类型元素个数元素个数;2022年8月
11、9日3时13分面向对象程序设计与Visual C+6.0教程21 int*p1;double*p2;p1=new int(12);p2=new double 100;l分别表示动态分配了用于存放整型数据的内存空间,将初值12写入该内存空间,并将首地址值返回指针p1;l动态分配了具有100个双精度实型数组元素的数组,同时将各存储区的首地址指针返回给指针变量p2;2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程22对象是类的实例,在创建了对象以后,编译系统将给对象分配存储空间。不同对象的区别主要表现在两个方面:对象名:即对象的标识符(外在区别);对象属性:即数据成员的值,
12、(内在区别)对象在定义的时需要初始化。对象生命期结束时要进行清理工作。C+中对象的创建与初始化、对象生命期中对象的创建与初始化、对象生命期结束时的清理工作,分别由构造函数和析构函结束时的清理工作,分别由构造函数和析构函数完成。数完成。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程23 构造函数的功能是在定义对象时由编译系统自动调用来创建对象并初始化对象。构造函数的函数名与类名相同。其定义格式如下:类名:类名类名:类名(参数表参数表)函数语句函数语句2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程24 构造函数的函数名与类名相同;构造函数可以
13、有任意类型的参数,但没有函数返回值类型;构造函数一般被定义为公有成员;构造函数在创建对象时由编译系统自动调用;构造函数只能一次性地影响对象的数据成员初值。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程25 如果类中没有定义构造函数,系统将自动生成一个默认形式的构造函数,用于创建对象,默认构造函数形式默认构造函数形式:默认构造函数默认构造函数类名:类名类名:类名()2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程26 构造函数是特殊的成员函数,函数体可写在类中,也可写在类外;若构造函数没有参数,则称为无参构造函数;若构造函数带有参数,则称为带
14、参数构造函数;构造函数可以重载;每个类都必须有一个构造函数。如果程序没有显式定义构造函数,编译系统将自动生成一个默认形式的构造函数。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程27析构函数不能有参数,也不能重载。定义格式如下:类名:类名:类名类名()函数语句函数语句2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程28 除对象生存期结束时自动调用外,在以下两种情况下析构函数会被调用:如果一个对象被定义在一个函数体内,如果一个对象被定义在一个函数体内,则当这个函数结束时。则当这个函数结束时。若一个对象是使用若一个对象是使用new运算符被动态创
15、运算符被动态创建的,在使用建的,在使用delete运算符释放它时。运算符释放它时。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程29 若没有显式定义析构函数,则系统自动生成一个默认形式的析构函数。系统自动生成的默认构造函数形式如下:系统自动生成的默认构造函数形式如下:类名:类名:类名类名()2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程30复制构造函数也是一种特殊的成员函数;功能是用一个已知的对象初始化一个被创建 的同类新对象;复制构造函数的参数是本类对象的引用;C+为每一个类定义了一个默认的复制构造函数;可以根据需要定义自己的复制构造函
16、数,从而实 现同类对象之间数据成员的值传递。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程31class 类名类名public:类名类名(参数表参数表);/构造函数构造函数 类名类名(const 类名类名&对象名对象名);/复制构造函数复制构造函数 ;类名:类名类名:类名(const 类名类名&对象名对象名)函数语句函数语句2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程32以下三种情况下由编译系统自动调用:声明语句中用类的一个已知对象初始化该类的另声明语句中用类的一个已知对象初始化该类的另一个对象时;一个对象时;当对象作为一个函数实参传递
17、给函数的形参时,当对象作为一个函数实参传递给函数的形参时,需要将实参对象去初始化形参对象时,需要调用复需要将实参对象去初始化形参对象时,需要调用复制构造函数;制构造函数;当对象是函数的返回值时,由于需要生成一个临当对象是函数的返回值时,由于需要生成一个临时对象作为函数返回结果,系统需要将临时对象的时对象作为函数返回结果,系统需要将临时对象的值初始化另一个对象,需要调用复制构造函数。值初始化另一个对象,需要调用复制构造函数。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程33复制构造函数名与类名相同,并且没有返回值类型;复制构造函数可写在类中,也可以写在类外;复制构造函
18、数有且仅有一个参数,即是同类对象的引用;如果没有显式定义复制构造函数,系统自动生成一个默认形式的复制构造函数。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程34类名:类名类名:类名(const 类名类名&对象名)对象名);2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程35关于浅复制:关于浅复制:在用一个对象初始化另一个对象时,只复制了数据成员,而没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制;默认复制构造函数所进行的是简单数据复制,即浅复制。关于深复制:关于深复制:通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制
19、了资源的复制方式称为深复制;自定义复制构造函数所进行的复制是深复制。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程36 静态成员提供了同一个类不同对象数据成同一个类不同对象数据成员的共享机制员的共享机制。静态成员包括:静态成员包括:静态数据成员 静态成员函数 2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程37static 静态成员的定义静态成员的定义;例如:例如:static int total;static void display();1.静态成员的定义与引用静态成员的定义与引用 2022年8月9日3时13分面向对象程序设计与Visu
20、al C+6.0教程38类名:静态成员名类名:静态成员名;静态成员的引用静态成员的引用 2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程39类型类型 类名:静态数据成员类名:静态数据成员=初始化值初始化值;对于类的普通数据成员,每一个对象都各自拥有一个副本;对于静态数据成员,每个类只拥有一个副本;静态数据成员初始化与一般数据成员初始化有所不同,其初始化格式如下:2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程40静态成员函数是指使用static关键字声明的成员函数;与静态数据成员一样,静态成员函数不是某一个类的成员,而是属于整个类;静态成员函
21、数可以直接访问该类的静态数据成员,而访问非静态数据成员则可以通过对象进行调用。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程41静态成员函数只能直接访问该类中的静态数据静态成员函数只能直接访问该类中的静态数据成员,而不会影响该类的其他数据成员;成员,而不会影响该类的其他数据成员;采用静态成员函数,可以在创建对象之前处理采用静态成员函数,可以在创建对象之前处理静态数据成员,这是普通成员函数不能实现的;静态数据成员,这是普通成员函数不能实现的;静态成员函数在同一个类只有一个成员函数的静态成员函数在同一个类只有一个成员函数的地址映射,节约了计算机系统的开销;地址映射,节约
22、了计算机系统的开销;静态成员函数不能直接访问类中的非静态成员。静态成员函数不能直接访问类中的非静态成员。如果静态成员函数需要访问非静态成员,需要通如果静态成员函数需要访问非静态成员,需要通过对象名才能访问该对象的非静态数据成员。过对象名才能访问该对象的非静态数据成员。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程42 若需要在类的外部直接访问类的私有数据成员,在C+中,通过定义友元可以实现这一功能。友元包括友元包括:友元函数友元函数 友元类友元类 2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程43 C+的友元提供了不同类或对象不同类或对象
23、的成员函数之间、类的成员函数与普通函数之间进行数据共享的机制。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程44非对称性(单向的)非对称性(单向的)若B是A的友元,若没有特别声明,则A不是B的友元。非传递性非传递性 若B是A的友元,C是B的友元,若没有特别声明,则C不是A的友元。友元的性质友元的性质2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程45 如果类外的非本类成员函数需要访问类的私有数据成员或保护成员,则需要将该函数声明为类的友元函数。友元函数的声明格式如下:friend 返回值类型返回值类型 函数名函数名(参数表参数表);2022
24、年8月9日3时13分面向对象程序设计与Visual C+6.0教程46友元函数可以访问类中的私有数据成员,但友元函数不是类的成员函数;友元函数可以是一个普通函数,也可以是另外一个类的成员函数;友元函数不是类的成员,因而与成员函数存在区别,友元函数不能直接使用对象名,而必须通过对象操作数据成员。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程47不仅函数可以声明为一个类的友元。一个类也可以声明为另一个类的友元。若一个类被声明为另一个类的友元,则该类的所有成员函数都是另一个类的友元。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程48friend
25、 类名;友元类的声明格式:友元类的声明格式:2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程49 C+标识符的作用域有函数原型作用域、块作用域(局部作用域)、函数作用域、类作用域和文件作用域。除类作用域外,其他作用域已在第3章介绍,2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程50 类作用域:类作用域:是指在类中定义的数据成员、成员函数及其他标识符的作用范围仅限定在该类中,即类作用域是指在类的声明中用一对花括号括起来的部分。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程51 生存期是一个时间概念;类对象的生存期是
26、指对象从被创建开始到生存期结束为止的时间;类对象在声明时被创建,在释放时被终止。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程52局部对象。局部对象是被定义在一个程序快或函数体内的对象,它的作用域范围小、生存期短。静态对象。静态对象被定义在一个文件中,它的作用域从定义时开始到文件结束时止,它的作用域范围大,生存期也较长。全局对象。全局对象的作用在域整个程序中,它的作用域范围最大、生存期也最长。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程53 一般情况下,如果C+程序中出现两个变量、函数名或类名的名字完全相同,就会产生冲突。解决命名冲突的
27、办法有两个:解决命名冲突的办法有两个:第一种解决方法是重新使用不同的标识符名,第一种解决方法是重新使用不同的标识符名,但有时为了程序的可读性,必须使用相同的标识名。但有时为了程序的可读性,必须使用相同的标识名。C+提供了第二种解决命名冲突的方法提供了第二种解决命名冲突的方法名空间。名空间。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程54枚举类型变量的声明格式如下:namespace 名空间标识符名名空间标识符名 成员的声明;成员的声明;2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程55使用名空间的成员时要用名空间名进行标识,从而有效解决
28、了标识符冲突。名空间成员的访问方式如下:名空间标识符名:成员名名空间标识符名:成员名2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程56为解决数据共享与数据安全的统一,C+引入了常类型。常类型是指使用关键字const说明的类型,常类型的变量或对象成员的值在程序运行期间是不可改变的。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程57常引用的说明形式如下:const 类型说明符类型说明符&引用名引用名;例如:int n=18;const int&b=n;其中,b是一个常引用,它所引用的对象不允许更改。2022年8月9日3时13分面向对象程序设计
29、与Visual C+6.0教程58 如果在说明对象时用const限定,则被说明的对象为常对象。常对象的数据成员的值在整个生存期内不能被修改。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程59常对象的说明格式常对象的说明格式类名类名 const 对象名对象名;或:const 类名类名 对象名;对象名;2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程60常对象成员包括:常成员函数 常数据成员 2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程61 const说明的成员函数称为常成员函数常成员函数的说明格式如下:类型 函数
30、名(参数表)const;2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程62 const是函数类型的一个组成部分,因此在函数的实现部分也要使用关键字const。常成员函数不能修改对象的数据成员,也不能调用该类中没有由关键字const修饰的成员函数,从而保证了在常成员函数中不会修改数据成员的值。const参与区分函数重载。如果一个对象被说明为常对象,则通过该对象只能调用它的常成员函数。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程63 类的数据成员也可以是常量或常引用。类的数据成员中被const说明的数据成员称为常数据成员。如果类中说明了常数据成员,构造函数只能通过初始化列表对该数据成员进行初始化,而任何其他函数都不能对该成员赋值。2022年8月9日3时13分面向对象程序设计与Visual C+6.0教程642022年8月9日3时13分面向对象程序设计与Visual C+6.0教程65