




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
在定义类时不能对成员变量进行初始化,因为无法确定成员变量属于哪一个对象。成员变量一般都定义为私有属性,也不能在声明对象后利用赋值运算对成员变量进行初始化。成员变量的初始化一般是利用一个名为构造函数的成员函数来完成。3.1构造函数如何进行成员变量的初始化?
?
构造函数是一种特殊的成员函数,它是在创建对象时(声明或new动态创建)系统自动调用的成员函数。
构造函数的名字必须与类名同名
它不具有任何类型,不返回任何值。什么是构造函数:#include<iostream.h>classTime{private:inthour;intminute;intsecond;public:
Time(){hour=0;minute=0;sec=0;}//构造函数voidset_time();voidshow_time();};例为类Time添加构造函数。定义成员函数voidTime::set_time(){cin>hour;Cin>>minute;Cin>>sec;}voidTime::show_time(){cout<<hour<<“:”<<minute<<“:”<<sec<<endl;}
如果用户自己没有定义构造函数,则C++系统会自动生成一个构造函数,只是这个构造函数的函数体是空的,也没有参数,不执行初始化操作。
构造函数不需用户调用,也不能被用户调用。带参数的构造函数构造函数可以带参数,在调用不同对象的构造函数时,从外面将不同的数据传递给构造函数,以实现不同的初始化。构造函数首部一般格式为:构造函数名(类型1形参1,类型2形参2….);实参在定义对象时给出,定义对象的一般格式为:类名对象名(实参1,实参2,….);例3.2有两个长方体,其长宽高为别为:(1)12,20,25;(2)10,14,20.分别求出它们的体积#include<iostream>usingnamespacestd;classBox{public:Box(int,int,int);intvolume();private:intheight;intwidth;intlength;};Box::Box(inth,intw,intlen){height=h;width=w;length=len;}intBox::volume(){return(height*width*length);}
intmain(){Boxbox1(12,25,30);cout<<"Thevolumeofbox1is"<<box1.volume()<<endl;Boxbox2(15,30,21);cout<<"Thevolumeofbox2is"<<box2.volume()<<endl;return0;}用带初始化表对数据成员初始化在函数首部对数据成员进行初始化:Box::Box(inth,intw,intlen):height(h),width(w),length(len){}表示:用形参h的值初始化数据成员height,用形参w的值初始化数据成员width,用形参len的值初始化数据成员length。构造函数的重载在一个类中可以定义多个构造函数,以便对类对象提供不同的初始化的方法,供用户选用。这些构造函数具有相同的名字,而参数的个数或参数类型不同例3.3定义两个构造函数,一个无参数,一个有参数#include<iostream>usingnamespacestd;classBox{public:Box();Box(inth,intw,intlen):height(h),width(w),length(len){}intvolume();private:intheight;intwidth;intlength;};Box::Box(){height=10;width=10;length=10;}intBox::volume(){return(height*width*length);}
intmain(){Boxbox1;cout<<"Thevolumeofbox1is"<<box1.volume()<<endl;Boxbox2(15,30,25);cout<<"Thevolumeofbox2is"<<box2.volume()<<endl;return0;}说明:调用构造函数不必给出实参的构造函数,称为默认的构造函数。一个类只能有一个默认的构造函数。建立对象时如果选用的是无参的构造函数,正确的格式是:Boxbox1;而不是:Boxbox1();一个类中可以包含多个构造函数,对每一个对象来说,建立对象时只执行其中一个构造函数使用默认参数的构造函数构造函数中参数的值既可以通过实参传递,也可以指定为某些默认的值。如果用户不指定实参值,编译系统就使形参取默认值。#include<iostream>usingnamespacestd;classBox{public:Box(int=10,int=10,int=10);intvolume();private:intheight;intwidth;intlength;};
Box::Box(inth,intw,intlen):height(h),width(w),length(len){}intBox::volume(){return(height*width*length);}
intmain(){Boxbox1;cout<<"Thevolumeofbox1is"<<box1.volume()<<endl;Boxbox2(15);cout<<"Thevolumeofbox2is"<<box2.volume()<<endl;Boxbox3(15,30);cout<<"Thevolumeofbox3is"<<box3.volume()<<endl;Boxbox4(15,30,20);cout<<"Thevolumeofbox4is"<<box4.volume()<<endl;return0;}说明:在声明构造函数时指定默认值,而不是在定义构造函数时指定默认值声明构造函数时,形参名可以省略:Box(int=10,int=10,int=10);如果构造函数的全部参数指定了默认值,则在定义对象的时候可以给出一个或者几个实参,也可以不给出实参。在一个类中定义了全部是默认参数的构造函数后,不能再定义重载构造函数。析构函数当一个对象生命周期结束时,其所占有的内存空间就要被回收,这个工作就由析构函数来完成。析构函数是“反向”的构造函数,析构函数不允许有返回值,更重要的是析构函数不允许带参数,并且一个类中只能有一个析构函数。被自动调用的情况有两种:在一个函数体内定义的一个对象,当函数结束时用new运算符动态创建的一个对象,在使用delete释放时析构函数的特点:析构函数的作用不是删除对象,而是在撤销对象占用的内存前完成一些清理工作,使这部分内存可以分配给新对象使用。析构函数不能重载。一个类可以有多个构造函数,只能有一个析构函数。#include<iostream>#include<string>usingnamespacestd;classStudent{public:Student(intn,stringnam,chars);~Student(){cout<<"Destructorcalled."<<endl;}voiddisplay(){cout<<"num:"<<num<<endl;cout<<"name:"<<name<<endl; cout<<"sex:"<<sex<<endl<<endl;}private:intnum;stringname;charsex;};Student::Student(intn,stringnam,chars){num=n;name=nam;sex=s;cout<<"Constructorcalled."<<endl;}intmain(){Studentstud1(10010,"Wang_li",'f');stud1.display();Studentstud2(10011,"Zhang_fun",'m');stud2.display();return0;}
程序的运行结果应该是什么?调用构造函数和析构函数的顺序一般情况下:先构造的后析构,后构造的先析构。注意:在全局范围中定义的对象,构造函数的调用在最前局部自动对象,在建立对象时调用其构造函数。在函数调用结束、对象释放时先调用析构函数。静态(static)局部对象,在程序第一次调用此函数建立对象时调用构造函数。在main函数结束或调用exit函数结束程序时,才调用析构函数。数组如果一批数据具有相同的属性,可以把这批数据看作一个有机整体,称为数组。用一个统一的名字代表这批数据,而用序号或下标来区分各个数据。简言之:数组是有序数据的集合。要寻找一个数组中的某一个元素必须给出数组名和下标。3.4对象数组定义对象数组格式为:<类名><数组名>[<大小>]…如:Studentstud[50];//共50个Student对象空间stud123…50stud[0]stud[1]stud[2]…stud[49]对象数组的初始化Student∷Student(int);//构造函数只有一个参数Studentstud[3]={60,70,78};Studentstud[3]={60,70,78,45};
×√Box∷Box(int,int,int)Boxbox1[3]={12,25,30};Box∷Box(int=1,int=1,int=1)Boxbox1[3]={12,25,30};建议Boxa[3]={Box(10,12,15),Box(15,18,20),Box(16,20,26)}×√使用对象数组的方法#include<iostream>usingnamespacestd;classBox{public:Box(inth=10,intw=12,intlen=15):height(h),width(w),length(len){}intvolume();private:intheight;intwidth;intlength;};intBox::volume(){return(height*width*length);}intmain(){Boxa[3]={Box(10,12,15),Box(15,18,20),Box(16,20,26)};cout<<"volumeofa[0]is"<<a[0].volume()<<endl;cout<<"volumeofa[0]is"<<a[1].volume()<<endl;cout<<"volumeofa[0]is"<<a[2].volume()<<endl;return0;}
3.5对象指针指向对象的指针
建立对象时,编译系统为每个对象分配一定的存储空间,以存放其成员。对象空间的起始地址就是对象的指针。因此可以定义一个指针变量,用来存放对象的指针。ClassTime{public:inthour;intminute;intsec;voidget_time(){cout<<hour<<“:”<<minute;cout<<“:”<<sec<<end;}};Time*pt;Timet1;pt=&t1;*pt(*pt).hourpt->hourpt->get_time();(*pt).get_time();
对象有地址,存放对象初始地址的指针变量是指向对象的指针变量。对象中的成员也有地址,存放对象成员地址的指针变量就是指向对象成员的指针变量。定义指向数据成员的指针变量的一般形式为:指向对象成员的指针数据类型名*指针变量名;如:int*p1;p1=&t1.hour;指向对象成员函数的指针指向普通函数的指针变量的定义方法:数据类型名(*指针变量名)(参数表列)如:void(*p)();给指针变量赋值:p=fun;用指针调用函数:(*p)()定义指向公有成员函数的指针变量的一般形式:数据类型名(类名::指针变量名)();如:void(Time::*p2)();p2=&Time::get_time;
成员函数与普通函数的一个根本区别是:它是类中的一个成员,不能在类外直接用用成员函数名作为函数入口去调用成员函数,因此要求指向成员函数的指针进行赋值的时候必须在以下三个方面匹配:(1)函数参数的类型和参数个数(2)函数返回值类型(3)所属的类classTime{public:Time(int,int,int);inthour;intminute;intsec;voidget_time();};Time∷Time(inth,intm,ints){hour=h;minute=m;sec=s;}voidTime∷get_time(){cout<<hour<<″:″<<minute<<″:″<<sec<<endl;}intmain(){Timet1(10,13,56);int*p1=&t1.hour;cout<<*p1<<endl;t1.get_time();Time*p2=&t1;p2->get_time();void(Time∷*p3)();p3=&Time∷get_time;(t1.*p3)();}This指针问题每个对象中的数据成员分别占用存储空间,如果同一个类定义了多个对象,则有n组同样大小的空间存放n个对象中的数据成员。但不同对象都调用同一个函数代码段。那么,当不同对象的成员函数引用数据成员时,怎么能保证引用的是所指定的对象的数据成员呢?在每一个成员函数中都包含一个特殊的指针,这个指针的名字是固定的,称为this。它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址。this指针是隐式使用的,它作为参数被传递给成员函数如在程序中成员函数volume定义如下:intBox::volume(){return(height*width*length);}C++把它处理为:intBox::volume(Box*this){return(this->height*this->width*this->length);}在调用成员函数a.volume时,实际上是用以下的方式调用的:a.volume(&a);将a的地址传递给this指针。然后按this的指向去引用各成员。共用数据的保护数据能在一定范围内共享,又要保证它不被任意修改,这时可以使用const,即把有关的数据定义为常量。
一般常量指简单类型的常量。如:constintm=15;m=20;intconstx=2;//一般常量定义时,两种方式一致。intconsta[5]={1,2,3,4,5};//元素为常量,不能修改×常对象
在定义对象时指定对象为常对象。常对象必须要有初值
Timeconstt1(12,34,46);
//t1是常对象如:classA{public:A(inti,intj):x(i),y(j){}…private:intx,y;};constAa1(3,4);Aconsta2(8,9);
一个对象被声明为常对象,则不能调用该对象的非const型的成员函数有时在编程时有要求,一定要修改常对象中的某个数据成员的值对该数据成员声明为mutable常数据成员如:constinthour;Time::Time(inth){hour=h;}Time::Time(inth):hour(h){}
在一个类中,有些数据成员的值允许改变,另一些数据成员的值不允许改变,则可以将一部分数据成员声明为const,以保证其值不被改变。注意×不能采用在构造函数中对常数据成员赋初值的方法,只能通过构造函数的参数初始化表对常数据成员进行初始化.常成员函数常成员函数,则只能引用本类中的数据成员,而不能修改它们。例如:输出数据成员,返回私有成员值等。如:voidget_time()const;常成员函数不能调用另一个非const成员函数。常成员函数可以引用const数据成员,也可以引用非const的数据成员。const数据成员可以被const成员函数引用,也可以被非const的成员函数引用。小结×指向对象的常指针将指针变量声明为const型,这样指针值始终保持为其初值,不能改变。Timet1(10,12,15),t2;Time*constptr=&t1;ptr=&t2;
定义指向对象的常指针的一般形式为:类名*const指针变量名=对象地址;且应该在定义指针变量时就使之初始化。Time*constptr1;ptr1=&t1;×注意:指向对象的常指针变量的值不能改变,即始终指向同一个对象,但可以改变其所指向对象中数据成员的值。当想将一个指针变量固定的与某一个对象相联系(即该指针变量始终指向一个对象),可以将它指定为const型指针变量。这样可以防止误操作,增加安全性。常用常指针作为函数的形参,目的是不允许在函数执行过程中改变指针变量的值,使其始终指向原来的对象。指向常对象的指针变量定义指向常变量的指针变量的一般形式为:const类型名*指针变量名constchar*p1;constcharc[]=“boy”;p1=c;说明:(1)如果一个变量已被声明为常变量,则只能用常指针指向它,而不能用一般的指针变量指向它。(2)指向常变量的指针可以指向长变量,也可以指向未被申明为const的变量(3)如果函数的形参是指向非const型变量的指针,实参只能是指向非const变量的指针;如果形参是指向const型变量的指针,实参可以是指向const变量的指针或非指向const变量的指针。定义指向常对象的指针变量的一般形式:Const类名*指针变量名Timet1(10,12,15);ConstTime*p=&t1;说明:(1)如果一个对象已被声明常对象,只能用指向常对象的指针指向它,不能用一般的指针变量去指向它(2)如果定义了一个指向常对象的指针变量,则使它指向一个非const的对象,则其指向的对象不能通过指针来改变。(3)指向常对象的指针最常用于函数的形参,目的是保护形参指针所指向的对象,使它在函数执行过程中不被修改。(4)定义了一个指向常对象的指针变量,不能通过它改变指向对象的值,但是指针变量本身的值可以改变定义指向常对象的指针变量的一般形式为:const类型名*指针变量名;定义指向对象的常指针的一般形式为:类名*const指针变量名;区分Time*constp//指向对象的常指针constTime*p//指向常对象的指针intmain(){voidfun(constTime*p);Timet1(10,13,56);fun(&t1);return0;}voidfun(constTime*p){p->hour=18;cout<<p->hour<<endl;}一条规则:
当希望在调用函数时对象的值不被修改,应当把形参定义为指向常对象的指针变量,同时用对象的地址作实参(对象可以是const或非const型)。如果要求改对象不仅在调用函数过程中不被改变,而且要求它在程序执行过程中都不改变,则应将它定义为const型(即常对象)。能否不用指针直接用对象名作为形参和实参,达到同样的目的呢?intmain(){voidfun(Timet)Timet1(10,13,56);fun(t1);cout<<t1.hour<<endl;return0;}voidfun(Timet){t.hour=18;}在函数中可以修改形参t的值,但不能改变其对应的实参t1的值。在函数调用过程中,将建立一个新的对象t,t是实参t1的拷贝。实参把值传给形参,二种分别占有不同的存储空间。这种形式的虚实结合,要产生实参的拷贝,当对象的规模较大时,时间和空间开销都比较大,因此常用指针作为函数参数。对象的常引用使用const来说明引用。该引用所引用的对象不能被更新。而引用本身是不能重新赋值,来实现对另一个对象的引用。classTime{ public: Time(int,int,int); inthour;intminute;intsec; };Time::Time(inth,intm,ints){hour=h;minute=m;sec=s;}例:voidfun(constTime&t){t.hour=18;}intmain(){Timet1(10,13,56);fun(t1);cout<<t1.hour<<endl;return0;}如果不希望在函数中修改t1的值,可以把引用变量t声明为const(常引用)则函数原型为:voidfun(constTime&);Const型数据的小结形式含义Timeconstt1或constTimet1t1是常对象voidTime::fun()constfun是Time类中的常成员函数,可以引用,但不能改变本类中的数据成员Time*constpp是指向Time类对象的常指针,p的值不能改变constTime*pp是指向Time类常对象的指针,其指向的类对象的值不能通过指针来改变Time&t1=tt1是Time对象t的引用,t和t1指向同一段内存空间对象的动态建立和释放1、new运算符用来动态创建对象。如:newBox;//编译系统开辟了一段内存空间,并在此空间中存放一个Box类对象,同时调用该类、//的构造函数,以使该对象初始化。用new运算符动态的分配内存后,将返回一个指向新对象的指针的值,即所分配的内存空间的起始地址。用户可以获得这个地址,并通过这个地址来访问这个对象。因此需要定义一个指向本类的对象的指针变量来存放这个地址。Box*pt;Pt=newBox;或Box*pt=newBox(12,15,18);2、delete运算符deletept;例:#include<iostream.h>classAA{public:AA(inti,intj){A=i;B=j; cout<<“Constructor.\n”;}~AA(){cout<<“Destructor.\n”;}voidprint();private:intA,B;};voidAA::print(){cout<<A<<“,”<<B<<endl;}voidmain(){AA*a1,*a2;a1=newAA(1,2);//动态创建对象a2=newAA(5,6);a1->print();a2->print();
deletea1;deletea2;}调用构造函数调用析构函数ConstructorConstructor1,25,6Destructor.Destructor.3.8对象的赋值和复制一、对象的赋值
如果一个类定义了两个或多个对象,则同类对象之间可以互相赋值。或者说,一个对象的值(对象中所有数据成员的值)可以赋给另一个同类的对象。对象赋值的一般形式是:对象名1=对象名2;注意:对象名1和对象名2必须属于同一个类。eg:Studentstud1,stud2;stud2=stud1;#include<iostream>usingnamespacestd;classBox{public:Box(int=10,int=10,int=10);intvolume();private:intheight;intwidth;intlength;};Box::Box(inth,intw,intlen){height=h;width=w;length=len;}
intBox::volume(){return(height*width*length);}
intmain(){Boxbox1(15,30,25),box2;cout<<"Thevolumeofbox1is"<<box1.volume()<<endl;box2=box1;cout<<"Thevolumeofbox2is"<<box2.volume()<<endl;return0;}对象的复制
有时候需要用过多个完全相同的对象。C++里面提供了克隆对象的方便易行的办法:对象的复制机制:Boxbox2(box1);//用已有的对象box1去克隆一个新对象box2.一般形式为:类名对象2(对象1);可以看出:给出的参数不是一般的变量,而是对象。建立一个新的对象时调用一个特殊的构造函数——复制构造函数复制构造函数实现了在初始化时将一个已知对象的数据成员的值拷贝给正在创建的另一个同类的对象。当然,它具有一般构造函数的所有特性。格式为:<类名>::<复制构造函数名>(<类名>&<引用名>){…}Box∷Box(constBox&b){height=b.height;width=b.width;length=b.length;}例:复制构造函数也是构造函数,只有一个参数,是本类的对象,采用对象的引用形式(一般约定加const声明)复制构造函数(续)C++还提供另外一种复制形式Boxbox2=box1;一般形式为:类名对象名1=对象名2;还可以在一个语句中进行多个对象的复制。如Boxbox2=box1,box3=box2;对象赋值与对象复制的区别:对象赋值是对一个已经存在的对象赋值,必须要先定义被赋值的对象才能赋值。对象的复制是从无到有的建立一个新对象,并使它与一个已有的对象完全相同(包括对象的结构和成员的值)。普通构造函数和赋值构造函数的区别:(1)形式上:类名(形参表列);//普通构造函数类名(类名&对象名);//复制构造函数(2)在建立对象时,实参类型不同。系统根据实参的类型决定调用普通的构造函数或复制构造函数复制构造函数被自动调用有三种情况:一、是用一个已知对象初始化一个新对象时二、是以值调用方式向一个函数传递对象参数时。三、当对象作为函数返回值时。voidfun(Boxb)//形参是类的对象{}intmain(){Boxbox1(12,15,18);fun(box1);//实参是类的对象,调用函数时将复制一个新对象breturn0;}Boxf()//函数f的类型为Box类类型{Boxbox1(12,15,18);returnbox1;//返回值是Box类的对象}intmain(){Boxbox2;//定义Box类的对象box2box2=f();//调用f函数,返回Box类的临时对象,并将它赋值给box2}静态成员
回顾:如果有n个同类的对象,那么每一个对象都分别有自己的数据成员,不同对象的数据成员各自有值,互不相干。如果希望有一个或者几个数据成员为所有对象所共有,希望实现数据共享怎么办?全局变量静态的数据成员静态数据成员静态数据成员是一种特殊的数据成员。它以关键字static开头。它为各对象所共有,而不只属于某个对象的成员。ClassBox{public:intvolume();private:staticintheight;intwidth;intlength;};说明:如果只声明了类而未定义对象,则类的一般数据成员是不占用空间的,只有定义对象时才为对象的数据成员分配空间。但静态成员不属于某个对象,在为对象分配的空间中不包括静态数据成员所占的空间。静态数据成员实在所有对象之外单独开辟空间。只要在类中定义了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被引用。静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放。静态数据成员在程序编译时被分配空间,到程序结束时释放空间。静态数据成员可以初始化,但只能在类体外进行初始化。intBox∷height=10;Box(inth,intw,intlen):height(h){}将height定义为公有成员,可以有如下访问方式:Boxa(15,20);cout<<a.height<<endl;cout<<Box∷height<<endl;例:#include<iostream>usingnamespacestd;classBox{public:Box(int,int);intvolume();staticintheight;intwidth;intlength;};Box::Box(intw,intlen){width=w;length=len;}intBox::volume(){return(height*width*length);}intBox::height=10;intmain(){Boxa(15,20),b(20,30);cout<<a.height<<endl;cout<<b.height<<endl;cout<<Box::height<<endl;cout<<a.volume()<<endl;return0;}有了静态数据成员,各对象之间的数据有了沟通的渠道,实现数据共享,因此可以不使用全局变量。全局变量破坏了封装的原则,不符合面向对象程序的要求。公有数据成员与全局变量的区别:静态数据成员的作用域只限于定义该类的作用域。在作用域内,可以通过类名和域运算符::引用数据成员,而不论该类对象是否存在。静态成员函数成员函数也可以定义为静态的,如:staticintvolume();静态成员函数是类的一部分,而不是对象的一部分。如果在类外要调用公有的成员函数,要用类名和域运算符::如:Box::volume();当然也允许通过对象名调用静态成员函数,如:a.valume()静态成员函数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员。注意静态成员函数并不属于某一对象,它与任何对象都无关.无法对一个对象中的非静态成员进行默认访问(即在引用数据成员时不指定对象名)。staticintvolume();{return(height*width*length);}如:×假设volume()是Box的成员函数:静态成员函数可以直接引用本类的静态数据成员。调用一个对象的成员函数(非静态成员函数)时,系统会把该对象的起始地址赋给成员函数的this指针。静态成员函数不属于某一个对象,它与任何对象都无关,因此静态成员函数没有this指针。静态成员函数与非静态成员函数的根本区别是:非静态成员函数有this指针,而静态成员函数没有this指针。因此静态成员函数不能进行默认访问本类中的非静态数据成员,可以直接引用本类中的静态数据成员。#include<iostream>usingnamespacestd;classStudent{public:Student(int,int,int);voidtotal();staticfloataverage();private:intnum;intage;floatscore;staticfloatsum;staticintcount;};
例Student::Student(intm,inta,ints){num=m;age=a;score=s;}
voidStudent::total(){sum+=score;count++;}
floatStudent::average(){return(sum/count);}floatStudent::sum=0;intStudent::count=0;intmain(){Studentstud[3]={Student(1001,18,70),Student(1002,19,79),Student(1005,20,98)};intn;cout<<"pleaseinputthenumberofstudents:";cin>>n;for(inti=0;i<n;i++)stud[i].total();cout<<"Theaveragescoreof"<<n<<"studentsis"<<stud[0].average()<<endl;return0;}3.10友元在一个类中可以有公用的(public)成员和私有的(private)成员。在类外可以访问公用成员,只有本类中的函数可以访问本类的私有成员。友元可以访问与其有好友关系的类中的私有成员。友元包括友元函数和友元类.友元函数概念:如果在本类以外的其他地方定义了一个函数(可以是不属于任何类的非成员函数,也可以是其他类的成员函数),在类中用friend对该函数进行声明,此函数就为本类的友元函数。作用:友元函数可以访问这个类中的私有成员。将普通函数声明为友元函数#include<iostream>usingnamespacestd;classTime{public:Time(int,int,int);friendvoiddisplay(Time&);private:inthour;intminute;intsec;};
Time::Time(inth,intm,ints){hour=h;minute=m;sec=s;}voiddisplay(Time&t){cout<<t.hour<<":"<<t.minute<<":"<<t.sec<<endl;}
intmain(){Timet1(10,13,56);display(t1);return0;}#include<iostream>usingnamespacestd;classDate;//对Data类的提前引用声明classTime{public:Time(int,int,int);voiddisplay(constDate&);private:inthour;intminute;intsec;};classDate{public:Date(int,int,int);friendvoidTime::display(constDate&);//声明Time类中的display函数为本类的友元函数private:intmonth;intday;intyear;};友元成员函数Time::Time(inth,intm,ints){hour=h;minute=m;sec=s;}voidTime::display(constDate&da){cout<<da.month<<"/"<<da.day<<"/"<<da.year<<endl;cout<<hour<<":"<<minute<<":"<<sec<<endl;}
Date::Date(intm,intd,inty){month=m;day=d;year=y;}
intmain(){Timet1(10,13,56);Dated1(12,25,2004);t1.display(d1);return0;}classB;
classA{intF1(B&b);intF2(B&b)};
classB{private:intm;
friendintA::F1(B&)};intA::F1(B&b){returnb.m;}IntA::F2(B&b){returnb.m;}
//类中使用另一个类对象须先有其说明//把A中F1说明为友元
//正确:友元访问私有成员//错误:A中F2不是友元一个函数(包括普通函数和成员函数)可以被多个类声明为“朋友”,这样就可以引用多个类中的私有数据注意友元类将一个类(如B类)声明为另一个类(如A类)的“朋友”,B类称为A类的友元类。友元类B中的所有函数都是A类的友元函数
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 春夜喜雨:唐诗鉴赏及创作启发教学教案
- 老旧小区改造工程的策略及实施路径
- 现代企业管理理论与实务试题集汇编
- 我的心爱之物物品介绍作文(5篇)
- 软件测试技术与实践题目解析
- 《数学微积分基本概念与运用教案》
- 国际贸易发展趋势研究表格
- 书中寻宝记读后感演讲稿15篇
- 2025年物理学高考复习综合测试卷及答案
- 2025年生态学与可持续发展专业考试知识试题及答案
- 英语简单句专项练习题含参考答案
- 2023年甘肃省酒泉市中考语文试卷【含答案】
- 湖北襄阳市检察机关-襄阳市城郊地区检察院招考聘用67人模拟预测(共500题)笔试参考题库附答案详解
- 2023-2024学年河南省濮阳市小学语文五年级期末提升测试题附参考答案和详细解析
- 延长石油笔试题库
- 阿里巴巴开店注意事项
- 思想政治理论综合实践知到章节答案智慧树2023年太原理工大学
- 脐灸技术评分标准
- 旅游俄语知到章节答案智慧树2023年海南外国语职业学院
- 乡村规划原理智慧树知到答案章节测试2023年同济大学
- ArcGIS高级制图技术
评论
0/150
提交评论