《吉大课件C程序结构.ppt》由会员分享,可在线阅读,更多相关《吉大课件C程序结构.ppt(69页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Software College of Northeast Normal University C+C+Programming Language C+Programming Language Dr.Zheng XiaojuanAssociate ProfessorSoftware College of Northeast Normal UniversityOctober.20081Software College of Northeast Normal University C+第五章第五章 程序结构程序结构 2Software College of Northeast Normal Univ
2、ersity C+本本 章章 内内 容容 1.1.作用域与可见性作用域与可见性2.2.生存期生存期 3.3.局部对象和全局对象局部对象和全局对象 4.4.静态成员静态成员 5.5.友元友元 6.6.常类型常类型7.7.编译预处理编译预处理 3Software College of Northeast Normal University C+类本身可被定义在三种作用域内:类本身可被定义在三种作用域内:1.1.全局作用域。全局类,绝大多数的全局作用域。全局类,绝大多数的C+C+类类是定义在该作用域中,我们在前面定义的所有类是定义在该作用域中,我们在前面定义的所有类都是在全局作用域中。都是在全局作用
3、域中。2.2.在另一个类的作用域中。嵌套类,即一在另一个类的作用域中。嵌套类,即一个类包含在另一个类中。个类包含在另一个类中。3.3.在一个块的局部作用域中。局部类,该在一个块的局部作用域中。局部类,该类完全被块包含。类完全被块包含。1 1 作用域与可见性作用域与可见性 4Software College of Northeast Normal University C+2 2 生存期生存期 2.1 2.1 静态生存期静态生存期 1.1.定义:与程序的运行期相同。静态生存期的变量程序开始运定义:与程序的运行期相同。静态生存期的变量程序开始运行就存在,直到程序运行结束生存期结束。具有文件作用域的
4、行就存在,直到程序运行结束生存期结束。具有文件作用域的变量具有静态生存期。变量具有静态生存期。2.2.语法声明:语法声明:static static 。例如,例如,static int kstatic int k;3.3.分配空间:在固定的数据区域内分配空间。分配空间:在固定的数据区域内分配空间。4.4.初初始始化化:如如果果具具有有静静态态生生存存期期的的变变量量未未初初始始化化,则则自自动动初初始始化为化为0 0。5.5.静态变量种类:全局变量、静态局部变量。静态变量种类:全局变量、静态局部变量。5Software College of Northeast Normal Universit
5、y C+运行时的存储空间结构运行时的存储空间结构目标代码空间目标代码空间寄存器空间寄存器空间静态区空间静态区空间堆区空间堆区空间栈区空间栈区空间最大地址最大地址最小地址最小地址6Software College of Northeast Normal University C+2.2 2.2 局部生存期局部生存期 1.1.定定义义:在在块块作作用用域域中中声声明明的的变变量量具具有有局局部部生生存存期期。此此生生存存期诞生于声明点,而终止于其作用域的结束处。期诞生于声明点,而终止于其作用域的结束处。2.2.局部变量种类:具有局部生存期的变量,具有块作用域。局部变量种类:具有局部生存期的变量,具
6、有块作用域。块作用域内静态变量,具有静态生存期。块作用域内静态变量,具有静态生存期。例如:例如:void main()void main()static int k static int k;/./.7Software College of Northeast Normal University C+2.3 2.3 动态生存期动态生存期 定定义义:由由程程序序中中特特定定的的函函数数 (malloc(malloc()和和freefree()调调用用或或由由操操作作符符(newnew和和deletedelete)创创建建和和释释放放。具具有有动动态态生生存存期期的的变变量量在在内内存存的的堆堆区
7、区分分配空间。配空间。8Software College of Northeast Normal University C+#include#includeclass Clockclass Clock private:private:int Hour,Minute,Second;int Hour,Minute,Second;public:public:Clock()Clock()Hour=0;Hour=0;Minute=0;Minute=0;Second=0;Second=0;3 3 局部对象和全局对象局部对象和全局对象9Software College of Northeast Normal
8、 University C+void SetTime(int NewH,int NewM,int NewS);void SetTime(int NewH,int NewM,int NewS);void ShowTime();void ShowTime();Clock()Clock();void Clock:SetTime(int NewH,int NewM,int NewS)void Clock:SetTime(int NewH,int NewM,int NewS)Hour=NewH;Hour=NewH;Minute=NewM;Minute=NewM;Second=NewS;Second=Ne
9、wS;void Clock:ShowTime()void Clock:ShowTime()coutHour:Minute:Secondendl;coutHour:Minute:Secondendl;10Software College of Northeast Normal University C+Clock globClock;void main()coutFirst time output:endl;coutFirst time output:endl;globClock.globClock.ShowTime()ShowTime();globClock.globClock.SetTime
10、(10,30,45)SetTime(10,30,45);Clock myclock(globClock);Clock myclock(globClock);coutSecond time output:endl;coutSecond time output:endl;myclock.ShowTime();myclock.ShowTime();程序运行结果为程序运行结果为First time outputFirst time output:0 0:0 0:0 0Second time outputSecond time output:1010:3030:454511Software Colleg
11、e of Northeast Normal University C+#include#includeusing namespace std;using namespace std;int int i i;/;/文件作用域文件作用域int main()int main()i i=5;=5;int int i i;/;/块作用域块作用域 i i=7;=7;couti=couti=i iendl;/endl;/输出输出7 7 couti=couti=i i;/;/输出输出5 5 return 0;return 0;作作用用域域与与可可见见性性例例12Software College of Nort
12、heast Normal University C+#include#includeusing namespace std;using namespace std;int int i i=5;/=5;/文件作用域文件作用域int main()int main()couti=couti=i iendl;endl;return 0;return 0;i i具有静态生存期具有静态生存期对对象象的的生生存存期期例例13Software College of Northeast Normal University C+#includeusing namespace std;void fun();int
13、main()fun();fun();void fun()static int a=1;int i=5;a+;i+;couti=i,a=aendl;运行结果:运行结果:i=6,a=2i=6,a=2i=6,a=3i=6,a=3i i是动态生存期是动态生存期a a是静态生存期是静态生存期对对象象的的生生存存期期例例14Software College of Northeast Normal University C+#includeusing namespace std;int i=1;/i 为全局全局变量,具有静量,具有静态生存期。生存期。int main()static int a;/静静态局部
14、局部变量,有全局寿命,局部可量,有全局寿命,局部可见。int b=-10;/b,c为局部局部变量,具有量,具有动态生存期。生存期。int c=0;void other(void);cout-MAIN-n;cout i:i a:a b:b c:cendl;c=c+8;other();cout-MAIN-n;cout i:i a:a b:b c:cendl;i=i+10;other();对对象象的的生生存存期期例例15Software College of Northeast Normal University C+void other(void)static int a=2;static int
15、 b;/a,b为静态局部变量,具有全局寿命,局部可见。为静态局部变量,具有全局寿命,局部可见。/只第一次进入函数时被初始化。只第一次进入函数时被初始化。int c=10;/Cint c=10;/C为局部变量,具有动态生存期,为局部变量,具有动态生存期,/每次进入函数时都初始化。每次进入函数时都初始化。a=a+2;i=i+32;c=c+5;cout-OTHER-n;cout i:i a:a b:b c:cendl;b=a;1716Software College of Northeast Normal University C+void Render(Image&image)void Rende
16、r(Image&image)class ColorTableclass ColorTable public:public:ColorTable(void)/*.*/ColorTable(void)/*.*/AddEntry(int r,int g,int b)/*.*/AddEntry(int r,int g,int b)/*.*/./.;ColorTable colors;ColorTable colors;/./.ColorTable ct;/ColorTable ct;/非法,没有定义非法,没有定义ColorTableColorTable类类!17Software College of
17、Northeast Normal University C+静态数据成员静态数据成员用关键字用关键字staticstatic声明声明该类的所有对象维护该成员的同一个拷贝该类的所有对象维护该成员的同一个拷贝必须在类外定义和初始化,用必须在类外定义和初始化,用(:)(:)来指明所属来指明所属的类。的类。静态成员函数静态成员函数类外代码可以使用类名和作用域操作符来调用类外代码可以使用类名和作用域操作符来调用静态成员函数。静态成员函数。静态成员函数只能引用属于该类的静态数据成静态成员函数只能引用属于该类的静态数据成员或静态成员函数。员或静态成员函数。4 4 静态成员静态成员 18Software Co
18、llege of Northeast Normal University C+4.1 4.1 静态数据成员静态数据成员 类的普通数据成员类的普通数据成员:类的静态数据成员类的静态数据成员:在类的每一个对象中都拥有一个拷在类的每一个对象中都拥有一个拷贝,每个对象的同名数据成员可以贝,每个对象的同名数据成员可以分别存储不同的数值,这也是每个分别存储不同的数值,这也是每个对象拥有自身特征的保证。对象拥有自身特征的保证。是类的数据成员的一种特例。是类的数据成员的一种特例。每个每个类只有一个静态数据成员拷贝类只有一个静态数据成员拷贝,它,它由该类的所有对象共同维护和使用,由该类的所有对象共同维护和使用,
19、从而实现了同一个类的不同对象之从而实现了同一个类的不同对象之间的数据共享。间的数据共享。静态数据成员具有静态数据成员具有静态生存期。静态生存期。19Software College of Northeast Normal University C+2.2.应用要点:应用要点:(1)声明:加声明:加staticstatic关键字说明。关键字说明。例如:例如:static int nstatic int n (2)(2)初初始始化化:在在定定义义时时初初始始化化,且且必必须须在在类类和和所所有有的的成成员员函函数数之之外外,与与全全局局变变量量初初始始化化的的方方法法一一样样。不不能能在在构构造造
20、函函数数中中初初始始化化。因因为为静静态态数数据据成成员员在在构构造造函函数数被被调调用用之之前前就就已已经经存存在了。形式:在了。形式::=例如:例如:int point:n=0;int point:n=0;(3)(3)引引用用:静静态态数数据据成成员员属属于于类类,而而不不属属于于任任何何一一个个对对象象,所所以,在类外通过类名对它进行引用。一般形式如下:以,在类外通过类名对它进行引用。一般形式如下::;20Software College of Northeast Normal University C+(4)静态数据成员访问控制限制静态数据成员访问控制限制:private/protec
21、ted:只只能能在在类类内内通通过过公公有有的的静静态态成成员员函数函数访问,在类外无法引用。访问,在类外无法引用。public:可可以以采采用用“类类名名:成成员员名名”或或“对对象象名名.成成员员名名”访问。访问。21Software College of Northeast Normal University C+【例例4 4】含有静态数据成员。含有静态数据成员。#include#includeclass Testclass Test private:private:int k;int k;public:public:static int n;static int n;Test(int
22、kk)k=kk;Test(int kk)k=kk;n+n+;void Display()void Display()coutn=n k=kendl;coutn=n k=kendl;n n为公有静态数据成员,用来给为公有静态数据成员,用来给TestTest类的对象计数,每声明一个类的对象计数,每声明一个新对象,新对象,n n的值就相应加的值就相应加l l。22Software College of Northeast Normal University C+int Test:n=0;int Test:n=0;/静态数据成员初始化静态数据成员初始化void main()void main()Tes
23、t Test t1(10)t1(10);t1.t1.Display()Display();Test t2(20);Test t2(20);t2.Display();t2.Display();Test:n+;Test:n+;(t1.n+t1.n+或或t2.n+)t2.n+)t2.Display();t2.Display();三次调用均访问的是三次调用均访问的是t1t1和和t2t2共同维护的该静态成员的拷共同维护的该静态成员的拷贝,这样实现了在贝,这样实现了在t1t1和和t2t2两两个对象间数据共享。个对象间数据共享。程程序序运运行行结结果果为为:n=1 k=10n=1 k=10n=2 k=20n
24、=2 k=20n=3 k=20n=3 k=20引用引用方法方法23Software College of Northeast Normal University C+练习练习:如果我们保持程序的其它部分不变,只将主函数中改为如果我们保持程序的其它部分不变,只将主函数中改为void main()void main()Test t1(10),t2(20);Test t1(10),t2(20);t1.Display();t1.Display();t2.Display();t2.Display();Test:n+;Test:n+;t2.Display();t2.Display();程序运行结果程序运行
25、结果?24Software College of Northeast Normal University C+4.2 4.2 静态函数成员静态函数成员 1.1.定定义义:使使用用staticstatic关关键键字字声声明明的的函函数数成成员员。同同静静态态数数据据成成员员一一样样,静静态态函函数数成成员员也也属属于于整整个个类类,由由同同一一个个类类的的所所有有对对象共同维护,象共同维护,为这些对象所共享。为这些对象所共享。2.2.静静态态成成员员函函数数如如何何访访问问成成员员数数据据:静静态态的的成成员员函函数数没没有有this指针指针 (1)(1)访问静态成员数据,可以直接使用其变量名来
26、访问;访问静态成员数据,可以直接使用其变量名来访问;(2)(2)访问非静态成员数据,需要使用访问非静态成员数据,需要使用“对象名对象名.成员名成员名”;3.公有的、静态的成员函数在类外的调用方式:公有的、静态的成员函数在类外的调用方式:类名类名:成员函数名成员函数名(实参表实参表)4.允许用对象调用静态的成员函数。允许用对象调用静态的成员函数。25Software College of Northeast Normal University C+【例例5 5】使用静态函数成员。使用静态函数成员。#include#include class Mclass Mpublic:public:M(int
27、 a)A=a;B+=a;M(int a)A=a;B+=a;static void f1(M m);static void f1(M m);private:private:int A;int A;static int B;static int B;void M:f1(M m)void M:f1(M m)cout“A=“cout“A=“m.Am.Aendlendl;cout“B=“cout“B=“B Bendl;endl;int M:B=0;int M:B=0;void main()void main()M P(5),Q(10);M P(5),Q(10);M:f1(P)M:f1(P);M:f1(Q
28、)M:f1(Q);访访问问静静态态成成员员数数据据,可可以以直直接接使使用用其其变变量量名名,访访问问非非静静态态成成员员数数据据,需需要要使使用用“对对象象名名.成员名成员名”;结果:结果:A=5A=5 B=15 B=15 A=10 A=10 B=15 B=1526Software College of Northeast Normal University C+#include#includeclass Aclass A private:private:int x;int x;public:public:static void f(A a);static void f(A a);void
29、A:f(A a)void A:f(A a)coutx;coutx;/对对x x的引用是错误的的引用是错误的 couta.x;couta.x;/正确正确 27Software College of Northeast Normal University C+【课堂练习课堂练习】阅读程序,写出程序运行结果阅读程序,写出程序运行结果#include#includeclass pointclass pointprivate:private:int x,y;int x,y;static int countP;static int countP;public:public:point(int xx=0,i
30、nt yy=0)point(int xx=0,int yy=0)x=xx;y=yy;x=xx;y=yy;countP+countP+;point(point&p);point(point&p);int get_x()return x;int get_x()return x;int get_y()return y;int get_y()return y;static void get_c()static void get_c()coutObject id=countPendl;coutObject id=countPendl;point:point(point&p)point:point(poi
31、nt&p)x=p.x;x=p.x;y=p.y;y=p.y;countP+;countP+;int point:countP=0;void main()point:get_c();/利用类名引用静态函数成员利用类名引用静态函数成员point a(4,5);coutpoint a,a.get_x(),a.get_y();a.get_c();/利用对象名引用静态函数成员利用对象名引用静态函数成员point b(a);coutpoint b,b.get_x(),b.get_y();point:get_c();/利用类名引用静态函数成员利用类名引用静态函数成员28Software College of
32、Northeast Normal University C+程序运行结果为程序运行结果为:Object id=0:Object id=0 point a,4,5 Object id=1 point a,4,5 Object id=1 point b,4,5 Object id=2 point b,4,5 Object id=229Software College of Northeast Normal University C+5 5 友元友元 1.1.含义:类的体内含义:类的体内以以friendfriend加以限定的非成员函数加以限定的非成员函数,从而可,从而可以在此函数体内利用对象访问类中
33、以在此函数体内利用对象访问类中privateprivate成员。成员。2.2.为什么需要友元:为什么需要友元:(1 1)在封装和快速性方面合理选择)在封装和快速性方面合理选择-类的主要特点是使实类的主要特点是使实现数据隐藏,既不允许非成员函数对它访问,但在某些场现数据隐藏,既不允许非成员函数对它访问,但在某些场合下,非成员函数体中需要通过对象名访问合下,非成员函数体中需要通过对象名访问privateprivate成员,成员,这可以通过友元函数来实现。这可以通过友元函数来实现。(2 2)有些函数需要放在外面或者类设计完后补充的,而不)有些函数需要放在外面或者类设计完后补充的,而不能成为成员函数,
34、但是又需要访问类中的私有成员。能成为成员函数,但是又需要访问类中的私有成员。3.3.作用:实现直接访问数据。作用:实现直接访问数据。30Software College of Northeast Normal University C+5.1 5.1 友元函数友元函数 1.1.定定义义:如如果果友友元元是是普普通通函函数数或或类类的的成成员员函函数数,则则称称为为友友元元函函数数。友友元元函函数数是是在在类类声声明明中中由由关关键键字字friendfriend修饰的非成员函数。修饰的非成员函数。2.2.语法:语法:(1 1)普通函数声明为友元函数的形式:)普通函数声明为友元函数的形式:frie
35、nd friend (参数表参数表)(2 2)成员函数声明为友元函数的形式:)成员函数声明为友元函数的形式:friend friend :(参数表参数表)31Software College of Northeast Normal University C+3 3.应用要点应用要点:(1 1)友友元元函函数数的的声声明明可可以以在在类类声声明明中中的的任任何何位位置置,既既可可在在publicpublic区,也可在区,也可在protectedprotected区,意义完全一样。区,意义完全一样。(2 2)友友元元函函数数的的定定义义一一般般放放在在类类的的外外部部,最最好好与与类类的的其其它它
36、成成员员函函数数定定义义放放在在一一起起。如如果果是是普普通通函函数数作作为为友友元元,也也可可以放在类中。以放在类中。(3 3)友友元元函函数数不不是是本本类类的的成成员员函函数数,但但是是它它可可以以通通过过对对象象名访问类的所有成员,包括私有和保护成员名访问类的所有成员,包括私有和保护成员。(4 4)要慎用友元。)要慎用友元。32Software College of Northeast Normal University C+【例例】普通函数作友元函数。普通函数作友元函数。#include#include#include#includeclass pointclass pointpri
37、vate:private:double x,y;double x,y;public:public:point(double xx=0,double yy=0)x=xx;y=yy;point(double xx=0,double yy=0)x=xx;y=yy;double get_x()return x;double get_x()return x;double get_y()return y;double get_y()return y;friend double distance(point&p1,point&p2);friend double distance(point&p1,point
38、&p2);/普通函数作普通函数作pointpoint的友元的友元;33Software College of Northeast Normal University C+double distance(point&p1,point&p2)double distance(point&p1,point&p2)return(sqrt(p1.return(sqrt(p1.x x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y);p2.y);void main()void main()point m
39、yp1(1,1),myp2(4,5);point myp1(1,1),myp2(4,5);coutThe distance is:coutThe distance is:distance(myp1,myp2)distance(myp1,myp2)endl;endl;34Software College of Northeast Normal University C+【例例】成员函数作友元函数。成员函数作友元函数。#include#include#include#includeclass point;class point;/前向声明前向声明pointpoint类类class Aclass A
40、 public:public:double distance(point&p1,point&p2);double distance(point&p1,point&p2);/./.;class pointclass point private:private:double double x,yx,y;35Software College of Northeast Normal University C+public:public:point(double xx=0,double yy=0)x=xx;y=yy;point(double xx=0,double yy=0)x=xx;y=yy;doub
41、le get_x()return x;double get_x()return x;double get_y()return y;double get_y()return y;friend friend double double A A:distance(point:distance(point&p1,point&p1,point&p2);&p2);/A/A类的成员函数作类的成员函数作pointpoint的友元的友元;double double A A:distance(point&p1,point&p2):distance(point&p1,point&p2)return(sqrt(p1.
42、return(sqrt(p1.x x-p2.-p2.x x)*(p1.)*(p1.x x-p2.-p2.x x)+(p1.)+(p1.y y-p2.p2.y y)*(p1.)*(p1.y y-p2.-p2.y y););36Software College of Northeast Normal University C+void main()void main()point myp1(1,1),myp2(4,5);point myp1(1,1),myp2(4,5);A obj;A obj;/声明一个声明一个A A类的对象类的对象coutThe distance coutThe distanc
43、e is:obj.distance(myp1,myp2)endl;is:obj.distance(myp1,myp2)endl;在主函数中一定要声明一个在主函数中一定要声明一个A A类的对象。只有类的对象。只有这样,才能通过对象名调用友元函数。这样,才能通过对象名调用友元函数。37Software College of Northeast Normal University C+4.4.普通函数作友元函数与成员函数对比:普通函数作友元函数与成员函数对比:(1 1)定义:原型定义)定义:原型定义-采用采用friendfriend加以限定;加以限定;函数体定义函数体定义-不必采用不必采用“类名类名
44、:”:”加以限定。加以限定。(2 2)调用方面:)调用方面:友元函数可直接调用,不必采用对象方式调友元函数可直接调用,不必采用对象方式调用。用。5.5.普通函数作友元函数与一般函数对比:普通函数作友元函数与一般函数对比:(1 1)定义:需要在类中加以原型说明(注册为友好成员)定义:需要在类中加以原型说明(注册为友好成员)(2 2)编程应用:)编程应用:友元函数体内可以访问类中的私有成员友元函数体内可以访问类中的私有成员。成元函数成元函数 友元函数友元函数 一般函数一般函数 “准成员函数准成员函数”安全性安全性-方便性方便性 折中折中38Software College of Northeast
45、 Normal University C+5.2 5.2 友元类友元类 1.1.如果友元是一个类,则称为友元类。如果友元是一个类,则称为友元类。2.2.语法声明形式:语法声明形式:friend class friend class 3.3.应用要点:应用要点:(1 1)友元类的声明同样可以在类声明中的任何位置。)友元类的声明同样可以在类声明中的任何位置。(2 2)友元类的所有成员函数都成为友元函数友元类的所有成员函数都成为友元函数。例例如如,若若A A类类为为B B类类的的友友元元类类,则则A A类类的的所所有有成成员员函函数数都是都是B B类的友元函数,都可以访问类的友元函数,都可以访问B
46、B类的私有和保护成员。类的私有和保护成员。39Software College of Northeast Normal University C+用友元类的方法重做例用友元类的方法重做例8 8。#include#include#include#includeclass point;class point;/前向声明前向声明pointpoint类类class Aclass Apublic:public:double distance(point&p1,point&p2);double distance(point&p1,point&p2);/./.;class pointclass point
47、40Software College of Northeast Normal University C+private:private:double double x,y;x,y;public:public:point(double xx=0,double yy=0)x=xx;y=yy;point(double xx=0,double yy=0)x=xx;y=yy;double get_x()return x;double get_x()return x;double get_y()return y;double get_y()return y;friend class A;friend cl
48、ass A;/A/A类为友元类类为友元类;double A:distance(point&p1,point&p2)double A:distance(point&p1,point&p2)return return(sqrt(p1.(sqrt(p1.x x-p2.-p2.x x)*(p1.)*(p1.x x-p2.-p2.x x)+(p1.)+(p1.y y-p2.p2.y y)*(p1.)*(p1.y y-p2.-p2.y y););41Software College of Northeast Normal University C+void main()void main()point m
49、yp1(1,1),myp2(4,5);point myp1(1,1),myp2(4,5);A obj;/A obj;/必须声明一个必须声明一个A A类的对象类的对象coutThe distance is:“coutThe distance is:“obj.distance(myp1,myp2)endl;obj.distance(myp1,myp2)endl;友元类的成员函数可以通过对象名友元类的成员函数可以通过对象名直接访问到隐藏的数据,达到高效直接访问到隐藏的数据,达到高效协调工作的目的。协调工作的目的。42Software College of Northeast Normal Unive
50、rsity C+4.4.两点注意:两点注意:友友元元关关系系是是不不能能传传递递的的。B B类类是是A A类类的的友友元元,C C类类是是B B类类的的友友元元,C C类类和和A A类类之之间间如如果果没没有有声声明明,就没有任何友元关系,不能进行数据共享。就没有任何友元关系,不能进行数据共享。友友无无关关系系是是单单向向的的。如如果果声声明明B B类类是是A A类类的的友友元元,B B类类的的成成员员函函数数就就可可以以访访问问A A类类的的私私有有和和保保护护数数据据,但但A A类类的的成成员员函函数数却却不不能能访访问问B B类类的的私有和保护数据。私有和保护数据。43Software