C语言程序设计 第二章 封装性:类和对象_第1页
C语言程序设计 第二章 封装性:类和对象_第2页
C语言程序设计 第二章 封装性:类和对象_第3页
C语言程序设计 第二章 封装性:类和对象_第4页
C语言程序设计 第二章 封装性:类和对象_第5页
已阅读5页,还剩112页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

《C++面向对象程序设计》教学内容

第一章 C++更好的C

第二章 封装性:类和对象第三章 运算符重载第四章 继承性:派生类第五章 多态性:虚函数第六章 模板第七章 类库和标准库第八章 异常处理第二章类和对象§2.1类和对象的定义与实现§2.2构造函数和析构函数§2.3对象指针和this指针§2.4静态成员§2.5类的对象成员§2.6常成员函数§2.7对象数组§2.8对象作为函数参数§2.9友元(friends)§2.10什么是面向对象程序设计?§2.1类和对象的定义与实现一.C++中类的定义和实现二.C++中类的接口与实现三.C++中对象的说明和使用一.类的定义和实现在C++语言中,我们通过定义新的数据类型来实现类。类既包含数据内容又包含对数据的操作,所以类是一个抽象数据类型。在C++语言中,类可被视为一种用户定义的类型。C++语言对结构的扩充C++中的结构不仅可以包含不同类型的数据,而且还可以包含函数。结构中的数据和函数都是结构的成员,分别称为数据成员和函数成员。在C++中,通常把函数成员称为成员函数。一个复数结构的例子structcomplex{doublereal;doubleimage;voidinit(doubler,doublei){real=r;image=i;}doublerealcomplex(){returnreal;}…;};成员函数数据成员私有成员和公有成员在C++中一个结构的成员通常分为两类:私有成员(private)和公有成员(

public)私有成员只能被该结构中的其他成员访问。公有成员既可以被结构内的其他成员访问,也可以被结构外的成员所访问。C++规定,在缺省情况下,结构中的成员是公有的。此处所指成员包括数据成员和成员函数。私有成员和公有成员的声明structcomplex{private:doublereal;doubleimage;public:voidinit(doubler,doublei){real=r;image=i;}doublerealcomplex(){returnreal;}…;};私有成员公有成员类的声明class

类名{[private:]

私有数据成员和成员函数public:

公有数据成员和成员函数};//分号是不能少的//其中,class是声明类的关键字//类名是要声明的类的名字类中私有成员和公有成员的声明classcomplex{private:doublereal;doubleimage;public:voidinit(doubler,doublei){real=r;image=i;}doublerealcomplex(){returnreal;}…;};私有成员公有成员类与结构的异同结构和类的唯一区别是:在缺省情况下结构内数据成员和成员函数是公有的public,而类中的数据成员和成员函数是私有的private。可以说C++中的结构是一种特殊的类。类(或者结构)的私有成员只能被该类(或者结构)的成员函数访问,这是C++实现封装的一种方法。声明类时的注意事项private和public可以按任意顺序出现具有良好习惯的程序员会:把所有私有成员和公有成员归类放在一起将私有成员放在公有成员的前面private、public和protected称为访问控制符。数据成员可以是任何数据类型,但不能用auto、register或extern进行说明。只有在类对象定义之后才能给数据成员赋初值。为什么要用类代替结构?在缺省情况下,类中的成员是私有的private。类提供了缺省的安全性。二.C++中类的接口与实现一般把仅含函数原型的类声明部分称为类的接口(interface),例如:classDate{ intday,month,year;public: voidinit(intdd,intmm,intyy);//initialize voidadd_year(intn); //addnyears voidadd_month(intn);//addnmonths voidadd_day(intn); //addndays}C++中类的接口与实现(续)把类中成员函数的定义部分称为类的实现部分(implementation)。例如:voidDate::init(intdd,intmm,intyy){ day=dd; month=mm; year=yy;}inlinevoidDate::add_year(intn){ year+=n;}C++中类的接口与实现(续)C++中的类实现了接口和实现的分离,这样只要维持接口不变,实现部分可以根据需要不断改进,而不影响类的使用。类的接口部分一般存放在扩展名为h的头文件中,类的实现部分则存放在扩展名为cpp的实现文件中。在cpp文件的开头要用include将h头文件包含在其中。这个特征增强了类模块的独立性和可重用性(reuse)。三.对象的说明和使用类对象的说明在C++语言中,类是用户定义的一种新类型,所以可以象声明普通变量一样来建立对象。在C++语言中,类与对象的关系就好象整型int和整型变量i之间的关系一样。注意:所有类对象都共享它们的成员函数,但是,每一个对象都建立并保持自己的数据。对象的数据成员,在C++中称为实例变量。创建对象的方法之一在定义类时同时创建对象,例如:classdate{intmonth,day,year;public:voidsetdate(int,int,int);voidprint();intgetyear();intgetmonth();intgetday();}tt;//同时创建对象tt。创建对象的方法之二在定义类后在创建对象,例如:Datadate1,date2;对象的使用对象的性质和定义要求将实例变量隐藏在对象中,对它们的访问,原则上要通过其接口——共有的成员函数来进行。访问对象的成员时,使用“.”运算符:对象名.成员名称;调用成员函数是必须指明对象,事实上,在C++语言中,我们用OOP术语发送消息来代替“调用成员函数”这个说法。§2.1类和对象的定义与实现§2.2构造函数和析构函数§2.3对象指针和this指针§2.4静态成员§2.5类的对象成员§2.6常成员函数§2.7对象数组§2.8对象作为函数参数§2.9友元(friends)§2.10什么是面向对象程序设计?第二章类和对象§2.2构造函数和析构函数一、构造函数constructor二、析构函数destructor三、实例分析—简单串类一、构造函数constructor构造函数是类的一种特殊成员函数,用来为对象进行初始化。构造函数的函数名与类名相同。构造函数的例子classDate{

intday,month,year;

Date(intdd,intmm,intyy);//constructor};voidDate::Date(intdd,intmm,intyy){ day=dd; month=mm; year=yy;}用来为对象进行初始化。构造函数(续)构造函数可以有任一类型的参数,但不能具有返回类型。当定义一个对象时,系统自动调用构造函数进行初始化。构造函数与其它函数一样可以重载也可以有缺省参数。在对象生成的时候自动执行初始化,这会消除任何错误地不执行初始化的可能。这是C++面向对象程序设计帮助减少复杂性的另一途径。有缺省参数的构造函数classcomplex{private:doublereal;doubleimage;public:voidcomplex(doubler=0.0,doublei=0.0){real=r;image=i;}doublerealcomplex(){returnreal;}…;};缺省参数重载构造函数主要有三个原因

1.

为了获得灵活性:提供给用户多种初始化对象的选项。2.

为了支持数组:要声明一个类的对象数组则该类应具有一个不带参数的构造函数。3.为了自定义复制构造函数,将对象进行准确的复制(拷贝):防止当传递对象给函数时出现错误,即当临时对象被撤销的时候,自动调用析构函数从而破坏作为参数的对象。参见简单串类。

重载构造函数例一classDate{ intd,m,y;public://... Date(int,int,int);//day,month,year Date(int,int);//day,month,today’syear Date(int);//day,today’smonthandyear Date();//defaultDate:today Date(constchar*);//dateinstringrepresentation};为了获得灵活性:提供给用户多种初始化对象的选项拷贝构造函数copyconstructor其作用是将参数代表的对象拷贝到新创建的对象中。自定义拷贝构造函数的一般形式如下:classname(constclassname&ob){…}若用户没有定义,编译器将产生一个缺省的复制构造函数。缺省的复制构造函数将源对象逐位地拷贝到目标对象。二、析构函数析构函数的作用与构造函数正好相反,当对象被删除时,利用析构函数进行一些善后处理。一般情况下析构函数执行构造函数的逆操作,例如可以利用析构函数来释放构造函数所动态申请的内存空间。析构函数的名称与其类名称相同,并在名称的前边加~(键盘上的波浪符号)符号。一个类中只能有一个析构函数。(不能重载)析构函数不允许有返回值,并且析构函数不允许带参数。参见例5。实例分析—简单串类串类的定义串类的实现串类的使用和分析串类的分析结果实现串类的定义//string.hppclassString{public:String();String(char*);String(int);String(constString&);~String();private:char*content;intlength};

串类的初步实现简单串类的初步实现

inlineString::String(){length=0;}inlineString::String(char*str){length=strlen(str);content=str;}inlineString::String(intlen){length=len;content=newchar[len];}简单串类的初步实现(续)inlineString::String(constString&s){length=s.length;content=s.content;}inlineString::~String(){deletecontent;}串类的使用及分析#include“string.hpp”Stings1(“test”);consts1testconstmain(){char*char;

str=newchar[20];

strcpy(str,”examples”);examplesstrimgs2(str);consts2string*ps;psps=newstring(s1);deletestr;deleteps;}简单串类实现的改进简单串类实现的改进//string.cpp#include<string.h>#include“string.hpp”inlineString::String(char*str){length=strlen(str);content=newchar[length];

strcpy(content,str);}简单串类实现的改进(续)inlineString::String(intlen){length=len;content=newchar[len];}inlineString::String(constString&s){length=s.length;content=newchar[length];

strcpy(content,s.content);}inlineString::~String(){deletecontent;}自定义复制构造函数析构函数§2.1类和对象的定义与实现§2.2构造函数和析构函数§2.3对象指针和this指针§2.4静态成员§2.5类的对象成员§2.6常成员函数§2.7对象数组(Objectarrays

)§2.8对象作为函数参数§2.9友元(friends)§2.10什么是面向对象程序设计?第二章类和对象§2.3对象指针和this指针可以定义指向对象的指针,在运用对象的指针的时候,对象的成员将用箭头运算符(→)而不是点运算符(.)引用。对象的指针算法与其它数据类型的指针算法相同:它被与对象相联系的处理。例如:当对象指针增加的时候,它指向下一个对象;当对象指针减少的时候,它指向前一个对象。this指针的引入对象是由数据和操作构成的一个整体,即使同一类的不同对象的操作也是相互独立的,各占不同的内存空间。但是,在C++实现中,这种处理方案太浪费内存空间。同类的对象能否共享该类成员函数的同一个实例呢?myBirthday.set(31,12,1997);nationalDay.set(1.10,1949);voidDate::Set(intD,intM,inty){day=D;month=M;year=Y;}那么,此时计算机怎么能区分该函数是作用在哪个对象上呢?解决方案C++在编译时,自动在每个成员函数中的第一个参数位置增加:

X*constthis;

当对象调用该函数时,编译器自动将该对象的指针作为实参传递给相应的函数,这样就可解决上述问题:voidDate::Set(Date*constthis,intD,intM,intY){this->day=D;this->month=M;this->year=Y;}

注:程序员不能将this指针的说明写在函数中this指针this指针是由C++编译器自动产生而使用的一个隐含指针,类成员函数使用该指针来存取对象的数据成员。

定义同一类的多个对象时,每个对象拥有自己的数据成员但它们共用一份成员函数,当成员函数存取对象的数据时它们使用this指针,通过this指针指向不同对象来决定使用哪一个对象的数据成员。this指针是如何在“幕后”工作?例如complex类中的init函数:voidinit(doubler,doublei){real=r;image=i;}C++编译器在编译这个函数时自动插入this指针:voidinit(complex*this,doubler,doublei){this->real=r;this->image=i;}this指针的显式使用this指针是系统的一个内部指针,通常以隐式方式使用,但也可以为程序员所使用,例如,当运算符重载和建立链表时this指针显得十分重要。参见双向链表This指针的显式用法显式地使用this指针,还可以使C++的编译器将同名的参数与数据成员区分开来:voidDate::Set(intday,intmonth,intyear){this->day=day;this->month=month;this->year=year;}§2.1类和对象的定义与实现§2.2构造函数和析构函数§2.3对象指针和this指针§2.4静态成员§2.5类的对象成员§2.6常成员函数§2.7对象数组(Objectarrays

)§2.8对象作为函数参数§2.9友元(friends)§2.10什么是面向对象程序设计?第二章类和对象§2.4静态成员

(staticmembers)一、静态数据成员二、静态成员函数一、静态数据成员声明类的静态数据成员的方式是在变量声明的前面加static关键字。classPeople{private:

staticintcount;intage;char*name;public:

staticinttotalAge;people(intold,char*string);…

};静态数据成员的初始化#include<iostream.h>staticintPeople::count=0;staticintPeople::totalAge=0;main(){Peoplemember(32,“Smith”)’Peoplemember(18,“John”);…}注意:在用People类生成任何对象之前,必须对其中的静态数据成员单独初始化。静态成员的访问当通过对象访问静态成员时,其访问规则与一般成员的相同,即只能访问公有成员。例如:

member1.totalage=100;//正确。

member1.count=12l//错。注意:静态数据成员要在生成该类的任何实例对象之前初始化,并且不能用构造函数初始化。

静态成员变量的应用静态成员变量的最一般的作用就是对一些共享资源提供存取控制。例如,可能创建几个对象,每个对象要对某个磁盘文件进行写操作,但显然在同一时间里只允许一个对象写文件。在这种情况下,程序员可能希望说明一个静态变量指出文件何时在使用,何时处于空闲状态。然后,每个对象在写文件之前询问这个对象。请看下面的例子:静态成员变量的例子#include"iostream.h"classcl{

staticintresource;public: intget_resource(); voidfree_resource(){resource=0;}};intcl::get_resource(){ if(resource)return0;//resourcealreadyinuse else{resource=1; return1;//resourceallocatedtothisobject }}静态成员变量的例子(续)intcl::resource=0;main(){

clob1,ob2; if(ob1.get_resource()) cout<<"ob1hasresource\n"; if(!ob2.get_resource()) cout<<"ob2deniedbyresource\n"; ob1.free_resource();//letsomeoneelseuseit. if(ob2.get_resource()) cout<<"ob2canuseresourcenow.\n"; return0;}在生成该类对象之前初始化替代全局变量静态数据成员属于整个类。不论定义多少个该类的对象,静态成员只有一个拷贝。该类所有的对象都可以通过这个成员实现数据共享。通过使用静态成员变量,实际上可以完全消灭全局变量。按照软件工程的原则,应该尽可能少地使用全局变量。二、静态成员函数在类中只使用静态数据成员的函数可以定义为静态成员函数。静态成员函数的定义方法是在原函数定义前加static关键字。对静态成员函数的引用与静态数据成员一样是利用所属的类加范围运算符。静态成员函数的声明在C++中,用static把一个成员函数声明成一个静态的成员函数。例如:

classX{private:intmember1;

staticintmember2;public:

staticvoidFun(intiv,X*p);};静态成员函数的访问静态成员函数的访问通常采用如下形式:

X::静态成员函数(X是类名)注意:构造函数和析构函数不能是静态的。静态函数没有this指针,只能访问静态的数据成员,要想访问非静态成员,必须将this指针显式地传给它。

voidX::Fun(intiv,X*p){member1=iv;//错,member1是非静态成员

p->member1=iv;//正确。

member2=iv;//正确。}§2.1类和对象的定义与实现§2.2构造函数和析构函数§2.3对象指针和this指针§2.4静态成员§2.5类的对象成员§2.6常成员函数§2.7对象数组(Objectarrays

)§2.8对象作为函数参数§2.9友元(friends)§2.10什么是面向对象程序设计?第二章类和对象§2.5类的对象成员(memberobjects)当一个类的对象作为一个类的成员时,称为该类的对象成员。使用对象成员着重要注意的问题是一个类的内部对象的初始化问题。类的对象成员初始化#include"iostream.h"classinner_class{ intx;public: inner_class(intz){x=z;} voidwrite(){cout<<x<<endl;}};类的对象成员初始化(续)classouter_class{ inty; inner_classx; inner_classr;public: outer_class(intz); voidwrite(){cout<<y<<endl;} voidwrite_inner_x() {x.inner_class::write();} voidwrite_inner_r() {r.inner_class::write();}};注意:outer_class类对象在通过构造函数进行初始化的同时,也要对其成员对象进行初始化。类的对象成员初始化(续)outer_class::outer_class(intz):x(20),r(-36){y=z;}main(){ outer_classobj(10);

obj.write_inner_x();

obj.write_inner_r();

obj.write(); return0;}初始化参数传递链初始化和撤销的顺序先里后外:先调用对象成员的构造函数,再调用外围类的成员函数。虽然对象成员调用它们类的构造函数,但此时写的是对象的名字,而不是类名。先外后里:当撤销一个包含对象成员的对象时,该对象的析构函数将先执行,然后再调用对象成员的析构函数。§2.1类和对象的定义与实现§2.2构造函数和析构函数§2.3对象指针和this指针§2.4静态成员§2.5类的对象成员§2.6常成员函数§2.7对象数组§2.8对象作为函数参数§2.9友元(friends)§2.10什么是面向对象程序设计?第二章类和对象§2.6常成员函数这是面向对象“罗曼史”中的一幕:对象A:亲爱的,你千万不能变心!对象B:放心吧!亲爱的,我是const。常成员函数

ConstantMemberFunctionsclassDate{ intd,m,y;public: intday()const{returnd;} intmonth()const{returnm;} intyear()const; //...};使用const关键字说明的函数常成员函数不更新对象的数据成员。(只读函数)常成员函数(续)inlineintDate::year()const//正确{ returny;}inlineintDate::year()//错误{ returny;}const是函数类型的一个组成部分,因此在实现部分也要带const关键字。遗漏了const关键字常成员函数(续)inlineintDate::year()const{ returny++;}将出现编译错误信息:企图在常成员函数中修改对象的数据成员。常对象constantobject常对象是指对象常量,定义格式如下:<类名>const<对象名>或者

const<类名><对象名>

例如:constDatecd;常对象constantobject(续)必须对常对象进行初始化,而且不能被更新。常对象只能调用它的常成员函数。普通的对象既可以调用它的常成员函数,也可以调用普通成员函数。请看下面的例子:常对象constantobject(续)voidf(Date&d,constDate&cd){ inti=d.year();//ok d.add_year(1);//ok intj=cd.year();//ok

cd.add_year(1);//错误}常对象不能调用它的普通成员函数常类型cosnt

常类型的变量或对象必须进行初始化,而且不能被更新。常数组:数组元素不能被更新。类型说明符const数组名[大小]...常引用:被引用的对象不能被更新。const类型说明符&引用名常指针:指向常量的指针(习题课介绍)。C++中const关键字使用得很广泛,主要目的是对共享数据的保护,提高软件的安全性。§2.1类和对象的定义与实现§2.2构造函数和析构函数§2.3对象指针和this指针§2.4静态成员§2.5类的对象成员§2.6常成员函数§2.7对象数组§2.8对象作为函数参数§2.9友元(friends)§2.10什么是面向对象程序设计?第二章类和对象§2.7对象数组(Objectarrays

)定义: 类名数组名[元素个数];例如:StudentaSA[10];//一个学生类对象数组通过下标访问方法: 数组名[下标].成员名;例如:aSA[j].print();对象数组初始化数组中每一个元素对象被创建时,系统都会调用构造函数类初始化该对象。通过初始化列表赋值。例:

LocationA[2]={Location(1,2),Location(3,4)};如果没有为数组元素指定显式初始值,数组元素使用缺省值初始化(调用缺省构造函数)。当数组中每一个对象被删除时,系统都要调用一次析构函数。数组元素所属类的构造函数没有自定义构造函数时,则采用缺省构造函数。各元素对象的初值要求为相同的值时,可以定义出具有缺省形参值的构造函数。各元素对象的初值要求为不同的值时,需要定义带形参(无缺省值)的构造函数。如果需要定义动态数组,需要一个无参构造函数。对象数组例子#include<iostream.h>classsamp{inta,b;public:

samp(intn,intm){a=n;b=m;}intget_a(){returna;}intget_b(){returnb;}};对象数组例子(续)main(){

sampob[4][2]={samp(1,2),samp(3,4),samp(5,6),samp(7,8),samp(9,10),samp(11,12),samp(13,14),samp(15,16),};inti;对象数组例子(续)

for(i=0;i<4;i++){cout<<ob[i][0].get_a();cout<<ob[i][0].get_b()<<"\n";cout<<ob[i][1].get_a();cout<<ob[i][1].get_b()<<"\n";}cout<<"\n";return0;}§2.1类和对象的定义与实现§2.2构造函数和析构函数§2.3对象指针和this指针§2.4静态成员§2.5类的对象成员§2.6常成员函数§2.7对象数组§2.8对象作为函数参数§2.9友元§2.10什么是面向对象程序设计?第二章类和对象§2.8对象作为函数参数在C++中,对象也可以象其它类型的数据一样,作为函数的参数。对象作为函数的参数时,实际参数与形式参数的传递方式也有两种:传送数值(传值调用CallbyValue)传送地址(传址调用CallbyReference)传值调用CallbyValue传值调用时,传送的是作为实际参数的对象的拷贝而不是实际对象本身。因此函数中对对象的任何修改均不影响作为实际参数的对象本身。创建形式参数对象时,是通过类的复制构造函数完成的。传值调用例子#include"iostream.h"classtr{inti;public:

tr(intn){i=n;}voidset_i(intn){i=n;}intget_i(){returni;}};voidsqrt_it(trob){ob.set_i(ob.get_i()*ob.get_i());cout<<"copyofobjhasivalueof"<<ob.get_i();cout<<"\n";}传值调用例子(续)main(){

trobj(10);

sqr_it(obj);cout<<"But,obj.iisunchangedinmain:";cout<<obj.get_i();return0;}对象obj以传值方式传送给临时对象传址调用CallbyReference传址调用时,传递的是作为实际参数的对象的地址;在函数中对作为形式参数的对象的修改实际上就是对作为实际参数的对象的修改。传址调用时,即可以使用指针,也可以使用引用。传址调用例子#include"iostream.h"classtr{inti;public:

tr(intn){i=n;}voidset_i(intn){i=n;}intget_i(){returni;}};voidsqrt_it(tr*ob){ob.set_i(ob->get_i()*ob->get_i());cout<<"copyofobjhasivalueof"<<ob->get_i();cout<<"\n";}传址调用例子(续)main(){

trobj(10);

sqr_it(&obj);cout<<"But,obj.iisunchangedinmain:";cout<<obj.get_i();return0;}传送对象obj的地址§2.1类和对象的定义与实现§2.2构造函数和析构函数§2.3对象指针和this指针§2.4静态成员§2.5类的对象成员§2.6常成员函数§2.7对象数组§2.8对象作为函数参数§2.9友元§2.10什么是面向对象程序设计?第二章类和对象§2.9友元(friends)一、友元函数(朋友函数friendsfunction)二、友元类一、友元函数1.一个类的友元函数是在该类中说明的一个非成员函数,但允许访问该类对象的所有成员。2.将关键字friend放在函数名的前面就将该函数说明为友元函数。3.友元函数的说明可以出现在类的私有部分或公有部分。程序员应将友元看作类的接口的一部分。友元函数举例#include<iostream.h>#include<math.h>classPoint{public:Point(doublexi,doubleyi){X=xi;Y=yi;}doubleGetX(){returnX;}doubleGetY(){returnY;}

frienddoubleDistance(Point&a,Point&b);private:doubleX,Y;};虽然友员函数在类内定义,但它不属于类的成员函数,所以没有this指针。因此必须在友元函数的参数表中显示地指出要访问的对象。

友元函数举例(续)doubleDistance(Point&a,Point&b){doubledx=a.X-b.X;doubledy=a.Y-b.Y;returnsqrt(dx*dx+dy*dy);}intmain(){Pointp1(3.0,5.0),p2(4.0,6.0);doubled=Distance(p1,p2);cout<<"Thedistanceis"<<d<<endl;return0;}访问对象中的成员必须通过对象名为什么引入友元?

1. 为了提高程序的效率;友元可以直接访问对象的私有成员,因而节省调用成员函数的开销。2. 类的使用者可以根据需要,通过使用友元来增加类的接口。3. 支持运算符重载。(在第三章中介绍)4.如果需要一个函数同时访问多个类,则它可以定义为多个类的友员函数。例如实现矩阵类对象和向量类对象相乘的函数矩阵类对象和向量类对象相乘的例子classMatrix;classVector{ floatv[4]; //... friendVectoroperator*(constMatrix&,constVector&);};classMatrix{ Vectorv[4]; //... friendVectoroperator*(constMatrix&,constVector&);};矩阵对象和向量对象相乘的例子(续)Vectoroperator*(constMatrix&m,constVector&v){ Vectorr; for(inti=0;i<4;i++){//r[i]=m[i]*v; r.v[i]=0; for(intj=0;j<4;j++)r.v[i]+=m.v[i].v[j]*v.v[j]; } returnr;}特别注意使用友元破坏了封装和数据隐藏,导致程序的可维护性差。因此使用友元时要慎重地权衡得失。

二、友元类若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员。定义语法:将友元类名在另一个类中使用friend修饰说明。友元类举例classA{friendclassB;public:voidDisplay(){cout<<x<<endl;}private:intx;}classB{public:voidSet(inti);voidDisplay();private:

Aa;};友元类举例(续)voidB::Set(inti){

a.x=i;}voidB::Display(){a.Display();}友员类的成员函数可以象友员函数一样访问该类的所有成员。

§2.1类和对象的定义与实现§2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论