1、C+程序设计第第3 3章章 类和对象类和对象第第3章章 类和对象类和对象本章学习要点本章学习要点类和对象的概念及其关系类的声明和对象的定义及使用构造函数与析构函数的作用及使用对象数组 对象与指针 对象与const对象的动态创建和释放对象的赋值和复制向函数传递对象学生信息管理系统中类的声明和对象的定义第第3章章 类和对象类和对象本章学习目标本章学习目标正确理解类、对象及封装的概念熟练掌握类的声明和对象的定义及使用理解构造函数与析构函数的作用及使用掌握对象与指针及const的特点及使用理解并掌握对象的赋值和复制理解对象作为函数的参数传递的实质掌握基本的基于对象的程序设计与实现3.1 类的声明和对象
2、的定义类的声明和对象的定义v本节主要是关于类和对象的概念、类的声本节主要是关于类和对象的概念、类的声明格式、对象的定义方法明格式、对象的定义方法 3.1.1 类和对象的概念及关系类和对象的概念及关系v对象对象 封装了数据及在这些数据之上的操作的封装了数据及在这些数据之上的操作的封装体封装体 v类类 对具有相同属性和操作的一组对象的抽对具有相同属性和操作的一组对象的抽象描述象描述 v类和对象的关系类和对象的关系 类是对象的抽象;对象是对类的实例化类是对象的抽象;对象是对类的实例化类和对象的关系类和对象的关系3.1.1 类和对象的概念及关系类和对象的概念及关系3.1.2 类类的声明的声明class
3、 类名类名public:公用成员公用成员 protected:受保护成员受保护成员 private:私有成员私有成员 ;声明类的一般形式:声明类的一般形式:声明类的关键字声明类的关键字合法标识符合法标识符公用成员限定符公用成员限定符受保护成员限定符受保护成员限定符私有成员限定符私有成员限定符类结束要加分号类结束要加分号3.1.2 类类的声明的声明【例例3-1】声明一个学生类,要求包括学生的学号、声明一个学生类,要求包括学生的学号、姓名、性别等信息,并且能够显示学生的信息。姓名、性别等信息,并且能够显示学生的信息。3.1.2 类类的声明的声明class Student /声明声明Student类
4、类public:/以下部分为公用成员函数以下部分为公用成员函数 void Show()coutNo.:stuNoendl;coutName:stuNameendl;coutSex:stuSexendl;private:/以下部分是私有数据成员以下部分是私有数据成员 int stuNo;char stuName20;char stuSex;/类声明结束,此处必须有分号类声明结束,此处必须有分号3.1.2 类类的声明的声明3.1.3 对象的定义对象的定义v声明类之后,再定义对象声明类之后,再定义对象 如:如:Student zhang,wang;或:或:class Student zhang,wa
5、ng;v在声明类的同时定义对象在声明类的同时定义对象 如:如:class Student zhang,wang;v不出现类名,直接定义对象不出现类名,直接定义对象 如:如:class zhang,wang;声明类时系统并不分配内存单元,而定义对象声明类时系统并不分配内存单元,而定义对象时系统会给每个对象分配内存单元时系统会给每个对象分配内存单元3.2.1 成员函数的性质成员函数的性质v不属于任何类的函数称为不属于任何类的函数称为普通函数普通函数。v成员函数隶属于某个类成员函数隶属于某个类v成员函数与普通函数的区别成员函数与普通函数的区别 成员函数是属于某个类的成员函数是属于某个类的,是类的一个
6、成员是类的一个成员 成员函数可以指定访问属性成员函数可以指定访问属性 成员函数可以访问本类的任何成员,而普通函成员函数可以访问本类的任何成员,而普通函数只能访问对象的公用成员数只能访问对象的公用成员v对于成员函数,对于成员函数,一般是将需要被类外调用一般是将需要被类外调用的声明为公用的,不需要被类外调用的声的声明为公用的,不需要被类外调用的声明为私有的。明为私有的。【例例3-4】将将Student类的成员函数改为在类外定义类的成员函数改为在类外定义的形式。的形式。3.2.2 在类外定义成员函数在类外定义成员函数class Student/声明声明Student类类型类类型public:/以下部
7、分为公用成员函数以下部分为公用成员函数 void Show();private:/以下部分是私有数据成员以下部分是私有数据成员 int stuNo;char stuName20;char stuSex;/类声明结束类声明结束/在类的声明之外定义成员函数在类的声明之外定义成员函数 void Student:Show()coutNo.:stuNoendl;coutName:stuNameendl;coutSex:stuSexendl;3.2.2 在类外定义成员函数在类外定义成员函数3.2.3 inline成员函数成员函数vinline函数函数 在编译时将被调用函数的代码直接嵌入在编译时将被调用函数
8、的代码直接嵌入到调用函数处到调用函数处 vinline成员函数就是将类中的成员函数成员函数就是将类中的成员函数声明为内置的声明为内置的 当类中的成员函数是在类内定义时,默当类中的成员函数是在类内定义时,默认该成员函数是认该成员函数是inline成员函数成员函数 如果成员函数定义在类的外部,则在成如果成员函数定义在类的外部,则在成员函数声明或定义前必须要有员函数声明或定义前必须要有inline关键关键字字 3.2.4 成员函数的存储方式成员函数的存储方式v实例化对象时需要分配内存空间,数据和函实例化对象时需要分配内存空间,数据和函数都需要存储空间数都需要存储空间v同一个类的不同对象的数据是不一样
9、的,因同一个类的不同对象的数据是不一样的,因此要为每个对象的数据成员分配内存单元此要为每个对象的数据成员分配内存单元v同一个类的不同对象的函数是一样的,因此同一个类的不同对象的函数是一样的,因此将同类的所有对象的函数放在一个公共的区将同类的所有对象的函数放在一个公共的区域。域。3.2.4 成员函数的存储方式成员函数的存储方式【例例3-5】类的对象占用内存空间实验。类的对象占用内存空间实验。#include using namespace std;class Testpublic:void Show()coutchar in Test is:cendl;private:char c;int ma
10、in()Test test;coutSize of Test is sizeof(test)endl;return 0;3.2.4 成员函数的存储方式成员函数的存储方式【例【例3-6】相同类的不同对象执行相同成员函数输出相同类的不同对象执行相同成员函数输出不同结果。不同结果。#include using namespace std;class Testpublic:void Set(char ch)c=ch;void Show()coutchar in Test is:cc=ch;void Show(Test*this)coutchar in Test is:c”运算符方便直观的进行,运算符方
11、便直观的进行,“-”称为指向运算符。称为指向运算符。例如:例如:Test test1;test1.Set(a);Test*pTest=&test1;test1.Show();pTest-Show();此处两个语句的执行结此处两个语句的执行结果完全相同,只是采用果完全相同,只是采用了不同的访问对象成员了不同的访问对象成员的形式而已的形式而已。3.3.3 通过引用访问成员通过引用访问成员v对象的引用和普通变量的引用在本质上是一样对象的引用和普通变量的引用在本质上是一样的的 v通过对象的引用访问对象成员和通过对象访问通过对象的引用访问对象成员和通过对象访问成员形式上是一样的成员形式上是一样的例如:例
12、如:Test test1;test1.Set(a);Test&refTest=test1;test1.Show();refTest.Show();此处两个语句的执行此处两个语句的执行结果完全相同,只是结果完全相同,只是采用了不同的访问对采用了不同的访问对象成员的形式而已象成员的形式而已。class Student/声明声明Student类类型类类型public:/以下部分为公用成员函数以下部分为公用成员函数 void Show();private:/以下部分是私有数据成员以下部分是私有数据成员 int stuNo;char stuName20;char stuSex;/类声明结束类声明结束/在
13、类的声明之外定义成员函数在类的声明之外定义成员函数 void Student:Show()coutNo.:stuNoendl;coutName:stuNameendl;coutSex:stuSexendl;int main()Student stud;stud.Show();return 0;class Student/声明声明Student类类型类类型public:/以下部分为公用成员函数以下部分为公用成员函数 void SetValue();void Show();private:/以下部分是私有数据成员以下部分是私有数据成员 int stuNo;char stuName20;char s
14、tuSex;/类声明结束类声明结束/在类的声明之外定义成员函数在类的声明之外定义成员函数 void Student:Show()coutNo.:stuNoendl;coutName:stuNameendl;coutSex:stuSexendl;void Student:SetValue()cout“Please input No,Name,Sex:“stuNostuNamestuSex;int main()Student stud;stud.SetValue();stud.Show();return 0;3.4.1 构造函数构造函数v构造函数的作用构造函数的作用 创建对象时对对象的数据成员初始
15、化创建对象时对对象的数据成员初始化 v构造函数的特点构造函数的特点 构造函数是类的一个特殊的成员函数,构造函数构造函数是类的一个特殊的成员函数,构造函数名与类名相同,且没有返回值名与类名相同,且没有返回值 构造函数不需要用户调用,由系统在创建对象时构造函数不需要用户调用,由系统在创建对象时自动调用的自动调用的 构造函数内容一般是初始化数据语句,但也可以构造函数内容一般是初始化数据语句,但也可以是其他的语句是其他的语句 创建对象时肯定会执行一个构造函数创建对象时肯定会执行一个构造函数class Student/声明声明Student类类型类类型public:/以下部分为公用成员函数以下部分为公用
16、成员函数 Student()stuNo=0;strcpy(stuName,);stuSex=M;void SetValue();void Show();private:/以下部分是私有数据成员以下部分是私有数据成员 int stuNo;char stuName20;char stuSex;/类声明结束类声明结束3.4.1 构造函数构造函数v带参数的构造函数带参数的构造函数 一般格式为:一般格式为:构造函数名构造函数名(参数表参数表);实参是在定义对象时给出的,一般格式实参是在定义对象时给出的,一般格式为:为:类名类名 对象名对象名(实参表实参表);v带参数的构造函数形式可以方便的实带参数的构造
17、函数形式可以方便的实现对不同对象进行不同的初始化现对不同对象进行不同的初始化【例【例3-10】定义两个长方体,分别求出它们的体积。定义两个长方体,分别求出它们的体积。这两个长方体的长宽高分别是这两个长方体的长宽高分别是4,2,3和和5,1,2。3.4.1 构造函数构造函数class Student/声明声明Student类类型类类型public:/以下部分为公用成员函数以下部分为公用成员函数 Student()stuNo=0;strcpy(stuName,);stuSex=M;void SetValue();void Show();private:/以下部分是私有数据成员以下部分是私有数据成员
18、 int stuNo;char stuName20;char stuSex;/类声明结束类声明结束#include using namespace std;class Boxpublic:Box(float L,float w,float h)/带有参数的构造函数 length=L;width=w;height=h;float Volume()return length*width*height;private:float length,width,height;int main()Box box1(4,2,3);/创建对象时给出实参 Box box2(5,1,2);coutVolume of
19、 box1 is box1.Volume()endl;coutVolume of box2 is box2.Volume()endl;return 0;3.4.1 构造函数构造函数v构造函数与参数初始化表构造函数与参数初始化表 这种方法不在构造函数的函数体内对数据成员这种方法不在构造函数的函数体内对数据成员初始化,而是在函数的首部实现初始化,而是在函数的首部实现。例如:例如:class Boxpublic:Box(float L,float w,float h):length(L),width(w),height(h)float Volume()return length*width*heig
20、ht;private:float length,width,height;使用参数初始化表的构造函数3.4.1 构造函数构造函数v 构造函数重载构造函数重载 在类中定义多个构造函数,这些构造函在类中定义多个构造函数,这些构造函数具有相同的函数名而参数表中参数的数具有相同的函数名而参数表中参数的个数或类型不同个数或类型不同 相当于给类实例化对象时提供了不同的相当于给类实例化对象时提供了不同的初始化方法初始化方法 3.4.1构造函数构造函数【例例3-12】构造函数重载。构造函数重载。#include using namespace std;class Boxpublic:Box()/无参数的构造函
21、数 length=1;width=1;height=1;Box(float L,float w,float h)/带有参数的构造函数 length=L;width=w;height=h;float Volume()return length*width*height;private:float length,width,height;int main()Box box1(4,2,3);Box box2;coutVolume of box1 is box1.Volume()endl;coutVolume of box2 is box2.Volume()endl;return 0;3.4.1构造函
22、数构造函数3.4.2 析构函数析构函数v析构函数的作用析构函数的作用 在系统释放对象之前进行清理工作。在系统释放对象之前进行清理工作。v析构函数的特点析构函数的特点 析构函数的函数名是固定的,由析构函数的函数名是固定的,由“”+“类名类名”组成组成 析构函数没有返回值析构函数没有返回值 析构函数没有参数析构函数没有参数 如果没有自己写出析构函数,系统会自如果没有自己写出析构函数,系统会自动生成一个析构函数动生成一个析构函数3.4.2 析构函数析构函数v析构函数的特点析构函数的特点 析构函数在对象生命周期结束时由系统析构函数在对象生命周期结束时由系统自动调用自动调用3.4.2 析构函数析构函数【
23、例3-13】带有析构函数的长方体类。class Boxpublic:Box()/无参数的构造函数 length=1;width=1;height=1;Box(float L,float w,float h)/带有参数的构造函数 length=L;width=w;height=h;float Volume()return length*width*height;Box()/析构函数 coutDestructor of Box is called!endl;private:float length,width,height;int main()Box box1(4,2,3);Box box2;co
24、utVolume of box1 is box1.Volume()endl;coutVolume of box2 is box2.Volume()endl;return 0;程序执行后运行的结果如下:程序执行后运行的结果如下:Volume of box1 is 24Volume of box2 is 1Destructor of Box is called!Destructor of Box is called!3.4.3 构造函数和析构函数调用次序构造函数和析构函数调用次序v总的原则总的原则 当创建对象时调用构造函数,当释放对当创建对象时调用构造函数,当释放对象时调用析构函数象时调用析构函数
25、 创建对象是当程序执行到了非静态对象创建对象是当程序执行到了非静态对象的定义语句或第一次执行到静态对象的的定义语句或第一次执行到静态对象的定义语句定义语句 释放对象则是对象到了生命周期的最后释放对象则是对象到了生命周期的最后时系统释放对象或通过时系统释放对象或通过delete运算符动态运算符动态释放释放new运算符动态申请的对象运算符动态申请的对象3.4.3 构造函数和析构函数调用次序构造函数和析构函数调用次序【例例3-14】验证调用构造函数和析构函数的顺序验证调用构造函数和析构函数的顺序的例子。的例子。教材教材P733.4.3 构造函数和析构函数调用次序构造函数和析构函数调用次序#inclu
26、de using namespace std;class Boxpublic:Box()Box(float L,float w,float h)Box()float Volume()return length*width*height;private:float length,width,height;int main()Box box1(4,2,3);Box box2;coutVolume of box1 is box1.Volume()endl;coutVolume of box2 is box2.Volume()endl;return 0;3.4.3 构造函数和析构函数调用次序构造函数和
27、析构函数调用次序int main()Box box1(4,2,3);Box box2;coutVolume of box1 is box1.Volume()endl;coutVolume of box2 is box2.Volume()endl;return 0;程序执行后运行的结果如下:程序执行后运行的结果如下:Box(4,2,3)is constructed!Box(1,1,1)is constructed!Volume of box1 is 24Volume of box2 is 1Destructor of Box(1,1,1)is called!Destructor of Box(4
28、,2,3)is called!3.5 对象数组对象数组v对象数组和普通的数组没有本质的区别,对象数组和普通的数组没有本质的区别,只不过普通的数组的元素是简单变量,而只不过普通的数组的元素是简单变量,而对象数组的元素是对象而已对象数组的元素是对象而已 v对象数组在实际中主要用于系统需要一个对象数组在实际中主要用于系统需要一个类的多个对象的情况类的多个对象的情况 v在建立数组时,系统会自动调用每一个对在建立数组时,系统会自动调用每一个对象元素的构造函数象元素的构造函数【例例3-15】创建含有创建含有3个长方体元素的长方体数组,个长方体元素的长方体数组,并显示长方体构造函数的调用情况。并显示长方体构
29、造函数的调用情况。教材教材P753.5 对象数组对象数组3.4.2 析构函数析构函数#include using namespace std;class Boxpublic:Box()Box(float L,float w,float h)Box()float Volume()return length*width*height;private:float length,width,height;int main()Box boxs3;/创建含有三个元素的对象数组boxs return 0;3.4.2 析构函数析构函数int main()Box boxs3;/创建含有三个元素的对象数组boxs
30、 return 0;程序执行后运行的结果如下:程序执行后运行的结果如下:Box(1,1,1)is constructed!Box(1,1,1)is constructed!Box(1,1,1)is constructed!Destructor of Box(1,1,1)is called!Destructor of Box(1,1,1)is called!Destructor of Box(1,1,1)is called!3.5 对象数组对象数组v对象数组在建立时还可以给出实参以对象数组在建立时还可以给出实参以实现对数组元素进行不同的初始化实现对数组元素进行不同的初始化 类有只有一个参数的构造
31、函数,可以使类有只有一个参数的构造函数,可以使用如下形式的数组初始化形式:用如下形式的数组初始化形式:Student students3=100,200,300;Student students3=100,200,300;如果对象的构造函数需要多个参数,则如果对象的构造函数需要多个参数,则在初始化的花括号里要分别写明构造函在初始化的花括号里要分别写明构造函数,并指定实参数,并指定实参 v对象数组初始化参见对象数组初始化参见【例例3-16】【例例3-16】定义对象数组并初始化,观察对象数组定义对象数组并初始化,观察对象数组建立的情况。建立的情况。教材教材P763.5 对象数组对象数组3.4.2
32、析构函数析构函数#include using namespace std;class Boxpublic:Box()Box(float L,float w,float h)Box()float Volume()return length*width*height;private:float length,width,height;int main()Box boxs3=Box(1,3,5),Box(2,4,6),Box(3,6,9);/创建含有三个元素的对象数组boxs return 0;3.4.2 析构函数析构函数int main()Box boxs3=Box(1,3,5),Box(2,4,
33、6),Box(3,6,9);/创建含有三个元素的对象数组boxs return 0;程序执行后运行的结果如下:程序执行后运行的结果如下:Box(1,3,5)is constructed!Box(2,4,6)is constructed!Box(3,6,9)is constructed!Destructor of Box(3,6,9)is called!Destructor of Box(2,4,6)is called!Destructor of Box(1,3,5)is called!3.4.2 析构函数析构函数int main()Box boxs3=Box(1,3,5),Box(),Box(
34、3,6,9);/创建含有三个元素的对象数组boxs return 0;程序执行后运行的结果如下:程序执行后运行的结果如下:Box(1,3,5)is constructed!Box(1,1,1)is constructed!Box(3,6,9)is constructed!Destructor of Box(3,6,9)is called!Destructor of Box(1,1,1)is called!Destructor of Box(1,3,5)is called!3.6 对象与指针对象与指针v以指针的概念为基础,同时又加入了以指针的概念为基础,同时又加入了对象的特点对象的特点 v对象与
35、指针主要从三个方面进行讨论对象与指针主要从三个方面进行讨论 指向对象的指针指向对象的指针 指向对象成员的指针指向对象成员的指针 this指针指针3.6.1 指向对象的指针指向对象的指针v指针指向的是内存中对象所占用空间的首指针指向的是内存中对象所占用空间的首地址地址v定义指向对象的指针的一般形式是:定义指向对象的指针的一般形式是:类名类名*指针名指针名;v通过指向对象的指针访问对象的成员有两通过指向对象的指针访问对象的成员有两种形式种形式 通过通过“-”调用对象的公用成员函数调用对象的公用成员函数 通过通过“*”运算符得到对象,然后再使用运算符得到对象,然后再使用“.”运算符调用对象的公用成员
36、函数运算符调用对象的公用成员函数 3.6.2 指向对象成员的指针指向对象成员的指针v指向对象数据成员的指针指向对象数据成员的指针 指向对象数据成员的指针和普通的指针是完全相同指向对象数据成员的指针和普通的指针是完全相同的声明指针变量的格式如下:的声明指针变量的格式如下:数据类型名数据类型名*指针变量名指针变量名;而使指针指向对象的公用数据成员使用如下语句:而使指针指向对象的公用数据成员使用如下语句:指针变量指针变量=&对象名对象名.数据成员名数据成员名;设类设类A有公用整型数据成员有公用整型数据成员data,定义了一个整型指,定义了一个整型指针针p和和A类对象类对象a,则,则 p=&a.dat
37、a;/使整型指针使整型指针p指向对象指向对象a的数据成员的数据成员data cout*pendl;3.6.2 指向对象成员的指针指向对象成员的指针v指向对象成员函数的指针指向对象成员函数的指针 指向对象成员函数的指针需要在指针名指向对象成员函数的指针需要在指针名前面加上所属的类名及域运算符前面加上所属的类名及域运算符“:”指向对象成员函数的指针不但要匹配将指向对象成员函数的指针不但要匹配将要指向函数的参数类型、个数和返回值要指向函数的参数类型、个数和返回值类型,还要匹配将要指向函数所属的类类型,还要匹配将要指向函数所属的类 3.6.2 指向对象成员的指针指向对象成员的指针v指向普通函数的指针变
38、量定义如下:指向普通函数的指针变量定义如下:v 返回值类型返回值类型(*指针名指针名)(参数表参数表);v而指向成员函数的指针变量定义如下:而指向成员函数的指针变量定义如下:v 返回值类型返回值类型(类名类名:*指针名指针名)(参数表参数表);v使用指向成员函数的指针指向一个公用成员函数时使用指向成员函数的指针指向一个公用成员函数时如下:如下:v 指针名指针名=&类名类名:成员函数名成员函数名;v使用指向成员函数的指针调用对象的成员函数时如使用指向成员函数的指针调用对象的成员函数时如下:下:v (对象名对象名.*指针名指针名)(实参表实参表);3.6.2 指向对象成员的指针指向对象成员的指针【
39、例例3-17】使用指向对象成员函数的指针调用对象的使用指向对象成员函数的指针调用对象的成员函数成员函数.int main()Box box(2,2,2);/创建创建Box的对象的对象box/定义指向定义指向Box类的成员函数的指针类的成员函数的指针p float(Box:*p)();/给指针给指针p赋值,使其指向赋值,使其指向Box类的成员函数类的成员函数Volume p=&Box:Volume;/调用指针调用指针p指向的函数指向的函数 coutVolume of box is(box.*p)()height)*(this-width)*(this-length)vthis指针是指向本类对象的
40、指针,它的指向指针是指向本类对象的指针,它的指向是被调用成员函数所在的对象是被调用成员函数所在的对象vthis指针是由系统通过参数隐式传递给成员指针是由系统通过参数隐式传递给成员函数的函数的this指针的处理过程指针的处理过程源程序编译后调用时float Box:Volume()return length*width*height;float Box:Volume(Box*this)return this-length*this-width*this-height;box1.Volume(&box1);3.7 对象与对象与constv在程序设计的过程中需要考虑的一个非常重要在程序设计的过程中需
41、要考虑的一个非常重要的因素就是数据的安全性的因素就是数据的安全性v在程序中,不同的模块之间经常出现需要共享在程序中,不同的模块之间经常出现需要共享数据的情况,此时数据的安全性降低数据的情况,此时数据的安全性降低v在程序中既要让数据在一定范围内共享在程序中既要让数据在一定范围内共享,又要又要保证数据的安全,这时可以使用保证数据的安全,这时可以使用const,把对,把对象或对象相关成员定义成常量象或对象相关成员定义成常量v本节主要从本节主要从常对象常对象、常对象成员常对象成员、指向对象的指向对象的常指针常指针、指向常对象的指针指向常对象的指针和和对象的常引用对象的常引用五五个方面进行说明个方面进行
42、说明3.7.1 常对象常对象v常对象中的所有成员的值都不能被修改常对象中的所有成员的值都不能被修改v常对象中数据成员为常变量且必须有初值常对象中数据成员为常变量且必须有初值v声明常对象的一般形式声明常对象的一般形式 const 类名类名 对象名对象名(实参表实参表);类名类名 const 对象名对象名(实参表实参表);v如果一个对象被声明为常对象,则不能调如果一个对象被声明为常对象,则不能调用该对象的非用该对象的非const型的成员函数(构造函型的成员函数(构造函数和析构函数除外)数和析构函数除外)v在成员函数声明的后面加上在成员函数声明的后面加上const即可访问即可访问3.7.2 常对象成
43、员常对象成员v常数据成员常数据成员 常数据成员的声明和作用与普通的常变量类似常数据成员的声明和作用与普通的常变量类似 在程序运行过程中常数据成员的值不能修改在程序运行过程中常数据成员的值不能修改 常变量在声明的同时必须初始化常变量在声明的同时必须初始化 注意常数据成员在初始化时必须使用构造函数注意常数据成员在初始化时必须使用构造函数的参数初始化表的参数初始化表3.7.2 常对象成员常对象成员 例:例:若若Box类中的数据成员类中的数据成员length声明为常数声明为常数据成员,则如下的构造函数:据成员,则如下的构造函数:Box:Box(float L,float w,float h)lengt
44、h=L;width=w;height=h;不能使用这种形不能使用这种形式进行初始化式进行初始化 Box:Box(float L,float w,float h):length(L)width=w;height=h;3.7.2 常对象成员常对象成员v常成员函数常成员函数 就是就是const型成员函数型成员函数 声明常成员函数的一般形式:声明常成员函数的一般形式:返回值类型返回值类型 成员函数名成员函数名(形参表形参表)constconst;常成员函数只能访问而不能修改数据成员的值,常成员函数只能访问而不能修改数据成员的值,如果在常成员函数中出现了修改数据成员值的如果在常成员函数中出现了修改数据成
45、员值的语句,系统编译是通不过的。语句,系统编译是通不过的。3.7.2 常对象成员常对象成员常成员函数非常成员函数 常数据成员可以访问,但不可修改值可以访问,但不可修改值 非常数据成员可以访问,但不可修改值可以访问,也可以修改值数据成员分类成员函数分类3.7.2 常对象成员常对象成员3.7.3指向对象的常指针指向对象的常指针v将指向对象的指针变量声明为将指向对象的指针变量声明为const型型v定义指向对象的常指针的一般形式:定义指向对象的常指针的一般形式:类名类名*const 指针名指针名=&类的对象类的对象;例如例如:Box box(2,2,2);Box*const pbox;pbox=&bo
46、x;v在给在给pbox赋初值后赋初值后pbox的值不能再修改的值不能再修改3.7.3 指向对象的常指针指向对象的常指针v一般情况下指向对象的一般情况下指向对象的const指针用指针用作函数的形参作函数的形参 指针在函数的执行过程中不会改变指针指针在函数的执行过程中不会改变指针的指向的指向 可以防止误操作,增加系统的安全性可以防止误操作,增加系统的安全性3.7.4 指向常对象的指针变量指向常对象的指针变量v指向常对象的指针变量和指向常变量的指针指向常对象的指针变量和指向常变量的指针变量的概念和用法非常接近变量的概念和用法非常接近v定义指向常对象的指针变量的一般形式:定义指向常对象的指针变量的一般
47、形式:const 类名类名*指针变量名指针变量名;v说明:说明:如果一个对象已被声明为常对象,只能用指向常如果一个对象已被声明为常对象,只能用指向常对象的指针变量指向它,而不能用一般的对象的指针变量指向它,而不能用一般的(指向指向非非const型对象的型对象的)指针变量去指向它指针变量去指向它 如果定义了一个指向常对象的指针变量,并使它如果定义了一个指向常对象的指针变量,并使它指向一个非指向一个非const的对象,则其指向的对象是不的对象,则其指向的对象是不能通过指针来改变的能通过指针来改变的3.7.4 指向常对象的指针变量指向常对象的指针变量v说明:说明:如果定义了一个指向常对象的指针变量,
48、虽然如果定义了一个指向常对象的指针变量,虽然不能通过它改变所指向的对象的值,但是指针不能通过它改变所指向的对象的值,但是指针变量本身的值是可以改变的变量本身的值是可以改变的 指向常对象的指针变量最常用于函数的形参,指向常对象的指针变量最常用于函数的形参,目的是在保护形参指针所指向的对象,使它在目的是在保护形参指针所指向的对象,使它在函数执行过程中不被修改函数执行过程中不被修改 当希望在调用函数时参数对象的值不被修改,当希望在调用函数时参数对象的值不被修改,就应当把形参定义为指向常对象的指针变量,就应当把形参定义为指向常对象的指针变量,同时用对象的地址作实参,而对象参数可以是同时用对象的地址作实
49、参,而对象参数可以是const或非或非const型。型。3.7.5 对象的常引用对象的常引用v对象的常引用表示一个对象的别名,但是无法通对象的常引用表示一个对象的别名,但是无法通过引用来修改对象的数据成员过引用来修改对象的数据成员v声明对象的常引用的一般形式:声明对象的常引用的一般形式:const 类名类名&引用名引用名=对象名对象名;v常引用的应用也是主要用在函数的形参中,保证常引用的应用也是主要用在函数的形参中,保证函数调用时实参对象的安全性函数调用时实参对象的安全性例如:例如:Clock clock(12,12,12);const Clock&refclock=clock;refcloc
50、k.Display();若若Display函数是函数是const成员函成员函数,则合法;数,则合法;若若Display函数是非函数是非const成员成员函数,则调用是非法的。函数,则调用是非法的。3.8 对象的动态创建和释放对象的动态创建和释放v使用使用new和和delete运算符实现对对象的动态运算符实现对对象的动态创建与释放创建与释放 v在程序执行到在程序执行到new语句时,系统会从内存语句时,系统会从内存堆中分配一块内存空间,存放类的对象,堆中分配一块内存空间,存放类的对象,调用构造函数初始化对象。如果内存分配调用构造函数初始化对象。如果内存分配成功,返回分配的内存的首地址;如果分成功,