《C程序设计实践教程下.pptx》由会员分享,可在线阅读,更多相关《C程序设计实践教程下.pptx(257页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、11.1 11.1 面向对象的思想什么是面向过程?什么是面向对象?两种不同的思想、方法。面向过程的程序设计用传统程序设计语言进行程序设计时,必须详细地描述解题的过程。程序设计工作主要围绕设计解题过程来进行,这种传统的程序设计方法称为面向过程的程序设计。第1页/共257页面向过程程序设计特点 程序处理数据的一系列过程;数据与过程分离;程序数据结构算法 缺点重用性差维护困难 第2页/共257页面向对象程序设计面向对象程序设计:将面向对象方法用于程序设计。出发点与基本原则:模拟人类习惯思维方式,使开发软件的方法尽可能接近人类认识世界解决问题的方法。对象作为模块,对象是对客观事物的自然的、直接的抽象和
2、模拟,包含了数据及对数据的操作。第3页/共257页11.2 11.2 面向对象程序设计的基本特点封装性将描述对象的数据及处理这些数据的代码集中起来放在对象内部,对象成为独立模块。继承性 从已有类(称为基类)派生出新类。多态性同一个名字代表不同、但相似的功能。第4页/共257页11.3 11.3 面向对象软件开发的基本过程软件危机促进了软件工程的形成与发展。软件工程:用系统工程学的原理和方法管理软件开发过程,开发过程分为分析、设计、编程、测试、维护等阶段。面向对象的软件工程分析:明确系统必须做什么。设计:明确软件系统怎么做。实现:选用合适的面向对象编程语言,实现设计阶段描述的软件系统的各个类模块
3、,并根据类的相互关系集成。测试:发现软件中的错误。维护:在软件交付用户使用期间,对软件所作的修改。第5页/共257页11.4 11.4 类和对象在面向对象程序设计中,对象是构成程序的模块,即程序是由一组对象构成的,对象之间通过消息分工协作,共同完成程序的功能。类是面向对象程序设计的核心,是对具有相同属性与行为的一组事物的抽象描述。利用类可以把数据和对数据所做的操作组合成一个整体,实现对数据的封装和隐藏。类是用户自定义的数据类型,是创建对象的模型。第6页/共257页11.4.1 11.4.1 类的定义 1格式关键字class 类名 成员1说明;成员2说明;成员n说明;;类定义体分号不可缺!分号不
4、可缺!第7页/共257页 2类的组成成员 数据成员:变量或对象。其类型为:其类型为:基本类型:intint、floatfloat、doubledouble、charchar、boolbool复合类型:数组、指针、引用、结构、枚举等成员函数 对数据成员进行操作。第8页/共257页n n例:例:class Circle private:int radius;public:void setRadius(int r)radius=r;double area()return 3.14*radius*radius;数据成员函数成员1?函数成员2第9页/共257页在定义一个类时,注意:类只是一种自定义数据类
5、型,类中任何成员数据均不能使用关键字extern、auto或register指定其存储类型,也不能初始化。例如:class Circle int radius=5;/错误 extern float pi;/错误 /省略其它成员 ;成员函数可直接使用类中的任一成员。类类型与结构体类型相似,结构体类型也可有函数成员,差别在于,类类型的缺省访问权限是private,结构体类型的缺省访问权限是public。第10页/共257页11.4.2 11.4.2 类成员的访问控制 访问权限控制访问权限控制访问权限访问权限private只允许同类的成员函数访问只允许同类的成员函数访问protected允许同类及其
6、派生类的成员函数访问允许同类及其派生类的成员函数访问public允许同一作用域的任何函数访问允许同一作用域的任何函数访问在定义类时,指定其成员访问权限的原则:仅供该类的成员函数访问的成员应指定为私有的。若定义的成员在派生类中也需经常使用,则应指定其为保护的。若允许在类外使用成员时,应将其访问权限定义为公有的。第11页/共257页11.4.3 11.4.3 类的成员函数及重载成员函数必须在类体内给出原型说明,至于它的实现,可以放在类体内,也可以放在类体外。当成员函数所含代码较少时,一般直接在类中定义该成员函数;当成员函数中所含代码较多时,通常只在类中进行原型的说明,在类外对函数进行定义。第12页
7、/共257页例:class Person class Person char name12;char name12;int age;int age;char sex4;char sex4;public:public:void Print()void Print()coutname,age,sexendl;coutname,age,sexendl;/省略其它成员;在类中定义的成员函数第13页/共257页在类外定义成员函数时,函数名应该包含:类名作用域分辩符(:)原函数名 指明该函数是哪个类的成员第14页/共257页class Person char name12;int age;char sex
8、4;public:void Print();/省略其它成员;void Person:Print()coutname,age,sex-数据成员名 对象指针名-成员函数名(参数表)第19页/共257页访问对象的成员时,要注意成员的访问权限。例:#include class Rectangle float length,width;public:float Area()return length*width;float Perimeter()return 2*(length+width);private:以关键字classclass定义的类,成员的缺省访问属性为privateprivate。第20页
9、/共257页void main()Rectangle r;r.width=45;r.length=54.2;coutthe area of rectangle is r.Area()endl;coutthe perimeter of rectangle is r.Perimeter()endl;非法访问 私有成员!第21页/共257页#include#includeclass Rectangleclass Rectangle float length,width;float length,width;public:public:void void SetWidthSetWidth(float
10、newWidth)(float newWidth)width=newWidth;width=newWidth;void void SetLengthSetLength(float newLength)(float newLength)length=newLength;length=newLength;float Area()float Area()return length*width;return length*width;float Perimeter()float Perimeter()return 2*(length+width);return 2*(length+width);例:第
11、22页/共257页void main()void main()Rectangle r;Rectangle r;/定义对象 r.r.SetWidthSetWidth(45);(45);r.r.SetLengthSetLength(54.2);(54.2);coutThe area of rectangle is coutThe area of rectangle is r.Area()endl;r.Area()endl;coutThe perimeter of rectangle is coutThe perimeter of rectangle is r.Perimeter()endl;r.P
12、erimeter()endl;第23页/共257页11.4.5 11.4.5 对象数组 若一个数组中每个元素都是同类型的对象,则称该数组为对象数组。定义一维对象数组的格式为:;第24页/共257页例11.5 对象数组的使用。#include class Circle int radius;public:void setRadius(int r)radius=r;int getRadius()return radius;double area()return 3.14*radius*radius;void main()Circle c3;c0.setRadius(6);c1.setRadius(
13、2);c2.setRadius(15);for(int i=0;i3;i+)coutradius:ci.getRadius(),area:ci.area()this-thisthis指针具有如下的缺省说明:Circle*const this;Circle*const this;第26页/共257页有时不得不显式使用this指针。数据成员名与函数成员的形参同名。例:class Name char*name;public:void SetName(char*name)if(name)this-name=new charstrlen(name)+1;strcpy(this-name,name);el
14、se this-name=NULL;第27页/共257页引用对象本身。例:class Name char*name;public:void CopyName(Name&n)if(this=&n)return;/避免对象自我复制 delete name;if(n.name)name=new charstrlen(n.name)+1;strcpy(name,n.name);else name=NULL;第28页/共257页11.5 11.5 构造函数和析构函数 构造函数和析构函数:类的特殊成员。构造函数:创建对象,并初始化对象的数据成员。析构函数:撤销对象,收回它所占内存,及完成其它清理工作。第2
15、9页/共257页11.5.1 11.5.1 构造函数 构造函数的定义格式 ClassName()/函数体它与所在类同名。它不得有返回值,甚至连关键字voidvoid也不许有。第30页/共257页 例:class Personclass Person char name12;char name12;int age;int age;char sex4;char sex4;public:public:Person(const char*n,int a,const char*s)Person(const char*n,int a,const char*s)strcpy(name,n);strcpy(n
16、ame,n);age=a;age=a;strcpy(sex,s);strcpy(sex,s);/省略其它成员函数;第31页/共257页 例:class Personclass Person char name12;char name12;int age;int age;char sex4;char sex4;public:public:Person(const char*n,int a,const char*s)Person(const char*n,int a,const char*s);/其它成员函数说明;Person:Person(const char*n,int a,const cha
17、r*s)Person:Person(const char*n,int a,const char*s)strcpy(name,n);strcpy(name,n);age=a;age=a;strcpy(sex,s);strcpy(sex,s);也可在类中声明原型,在类外定义。第32页/共257页 构造函数的特殊性:构造函数在定义类对象时由系统自动调用。例:void main()void main()Person p(Person p(“张三”,20,20,“男”););当遇此定义语句时,系统就调用构造函数:Person(const char*n,int a,const char*s)Person(
18、const char*n,int a,const char*s)创建对象p p,并用实参初始化它的数据成员。第33页/共257页构造函数可以重载。例:class Point class Point float x,y;float x,y;public:public:Point()x=0;y=0;Point()x=0;y=0;/(1)/(1)Point(float a,float b)x=a;y=b;Point(float a,float b)x=a;y=b;/(2)/(2)/;void main()void main()Point p1;Point p1;/匹配(1)(1)Point p2(2
19、.0,4.2);Point p2(2.0,4.2);/匹配(2)(2)第34页/共257页构造函数中初始化数据成员的方法在函数体中用赋值等语句进行使用成员初始化列表第35页/共257页初始化列表格式:在形参表和函数体之间,以:号开头,由多个以逗号分隔的初始化项构成。即 :数据成员名1(初值1),数据成员名n(初值n)举例:Person:Person():name(zhang),age(22)strcpy(sex,男);执行顺序:带有初始化表的构造函数执行时,首先执行初始化表,然后再执行函数体。第36页/共257页数据成员的初始化普通数据成员的初始化既可在函数体进行,也可在初始化表进行。例:(方
20、法1)1)Point:Point(int x1,int y1)Point:Point(int x1,int y1)x=x1;y=y1;x=x1;y=y1;或(方法2)2)Point:Point(int x1,int y1):x(x1),y(y1)Point:Point(int x1,int y1):x(x1),y(y1)constconst数据成员、数据成员、constconst对象成员和从基类继对象成员和从基类继承的数据成员的初始化必须用初始化表。承的数据成员的初始化必须用初始化表。第37页/共257页缺省的构造函数C+规定,每个类至少有一个构造函数,否则就不能创建该类的对象。例:class
21、 Rectangleclass Rectangle float length,width;float length,width;public:public:float Area();float Area();float Perimeter();float Perimeter();/类的实现void main()void main()Rectangle rect;Rectangle rect;能否创建RectangleRectangle类的对象?第38页/共257页类中若未定义构造函数,则C+编译系统自动提供一个缺省的构造函数。缺省的构造函数无参,函数体为空,仅创建对象,不作任何初始化工作。cl
22、ass Rectangleclass Rectangle float length,width;float length,width;public:public:float Area();float Area();float Perimeter();float Perimeter();/类的实现void main()void main()Rectangle rect;Rectangle rect;因系统提供了默认的构造函数:Rectangle()Rectangle()第39页/共257页只要类中定义了一个构造函数,C+编译器就不再提供缺省的构造函数,如还想要无参构造函数,则必须自己定义。例:c
23、lass Circle int radius;public:Circle(int r)radius=r;/(1);Circle c1;Circle c2(5);因该类有带一个参数的构造函数,故系统不再提供无参的缺省构造函数!匹配匹配(1)(1)没有无参构造函数没有无参构造函数第40页/共257页对上例的修改方法1:class Circle int radius;public:Circle(int r)radius=r;/(1)Circle()/(2);Circle c1(3);Circle c2;匹配匹配(1)(1)匹配匹配(2)(2)添加无参构造函数!第41页/共257页对上例的修改方法2:
24、class Circle int radius;public:Circle(int r=0)radius=r;/(1);Circle c1(3);Circle c2;匹配匹配(1)(1)匹配匹配(1)(1)参数带默认值的构造函数!参数带默认值的构造函数!所有参数都带默认值的构造函所有参数都带默认值的构造函数也是缺省的构造函数。数也是缺省的构造函数。第42页/共257页 使用参数带缺省值的构造函数时,应防二义性。如:class Circle int radius;public:Circle()/L1 Circle(int r=0)radius=r;/L2 ;Circle c1;/L3 错误!产生
25、二义性 Circle c2(5);/匹配L2行的构造函数 当编译L3行的语句时,出错。因Circle类定义了两个缺省的构造函数,编译器不知道是调用L1行定义的Circle()还是调用L2行定义的Circle(int r=0)。第43页/共257页11.5.2 11.5.2 析构函数作用:与构造函数相反,在对象被撤消时由系统自动调用,做清理工作。特点:析构函数名必须与类名相同,并在其前面加上字符“”,以便和构造函数名相区别。析构函数没有返回值,函数名前也不能用关键字void。析构函数没有参数,换言之,析构函数是唯一的,析构函数无法重载。第44页/共257页例11.9 调用析构函数。#includ
26、e class Point int x,y;public:Point()x=y=0;coutDefault constructor called.n;Point(int a,int b)x=a;y=b;coutConstructor with parameters called.n;Point()coutDestructor called.x,yn;void print()coutx,yn;为了观察调用构造函数和析构函数的过程,分别在构造函数和析构函数内添加了输出调用信息的语句。第45页/共257页 void main()Point p1(5,8),p2;p1.print();p2.print
27、();Point p2(3,2);p2.print();coutExit main!n;程序运行结果:Constructor with parameters called.Constructor with parameters called.Default constructor called.Default constructor called.5,85,80,00,0Constructor with parameters called.Constructor with parameters called.3,23,2Destructor called.3,2Destructor calle
28、d.3,2Exit main!Exit main!Destructor called.0,0Destructor called.0,0Destructor called.5,8Destructor called.5,8从该程序的输出结果看:当创建对象时,系统自动调用相匹配的构造函数;当撤销对象时,系统自动调用析构函数。对象撤销的顺序与创建的顺序正好相反。在相同的生存期的情况下,先创建的对象后撤销,后创建的对象先撤销。第46页/共257页若类的定义中没有显式定义析构函数,则编译器自动为该类产生一个缺省的析构函数。其格式为:ClassName:ClassName()它不执行任何操作。无需显式定义析
29、构函数的典型情况:撤消对象时不做任何清理工作。需要显式定义析构函数的典型情况:类中包含指向动态内存的指针数据成员。由于它们所指向的动态内存空间是对象自己管理的,因此在对象即将撤消时,需通过析构函数将所管理的动态内存空间及时释放。第47页/共257页例11.10 使用析构函数,收回动态分配的存储空间。#include#includeclass Person char*name;int age;public:Person(char*n,int a)if(n)name=new charstrlen(n)+1;strcpy(name,n);else name=0;age=a;Person()delet
30、e name;void Print()coutname,ageendl;void main()Person p(“John”,20);p.Print();申请动态内存释放动态内存第48页/共257页对象释放顺序:对象释放的顺序与创建的顺序正好相反。在相同的生存期的情况下,先创建的对象后释放,后创建的对象先释放。第49页/共257页11.5.3 11.5.3 构造函数的类型转换功能如果类定义中提供了只带一个参数(没有其它参数,或其它参数都有缺省值)的构造函数,则当一个其它类型的数值或变量x赋值给该类的对象A时,由于类型不一致,系统自动以x为实参调用该类的单参数构造函数,创建一个该类的临时对象,并
31、将该临时对象赋值给A,从而实现了隐式类型转换。第50页/共257页例11.11 构造函数完成类型转换功能的例子。#includeclass Money int yuan,jiao,fen;public:Money(double d)int t=d*100;yuan=t/100;jiao=(t-yuan*100)/10;fen=t%10;Money(int y=0,int j=0,int f=0)yuan=y;jiao=j;fen=f;void print()coutyuan“元”jiao“角”fen“分n;单参数构造函数第51页/共257页void main()Money m1(25,5,7)
32、,m2(2.65);m1.print();m2.print();Money m3=4.57;m3.print();m3=3.29;m3.print();隐式类型转换:调用单参数构造函数,创建MoneyMoney类型的临时对象。并不做隐式类型转换,等价于:Money m3(4.57);Money m3(4.57);第52页/共257页11.5.4 11.5.4 拷贝构造函数拷贝构造函数:特殊的构造函数,其形参是本类的对象的引用,其作用是使用一个已经存在的对象(由拷贝构造函数的参数指定的对象)去初始化一个新的同类的对象。定义一个拷贝构造函数的一般形式为:ClassName:ClassName(Cl
33、assName&c)./函数体完成对应数据成员的赋值第53页/共257页例11.12 使用完成拷贝功能的构造函数。#include#includeclass Point int x,y;public:Point(int a=0,int b=0)x=a;y=b;Point(Point&t)/拷贝构造函数 x=t.x;y=t.y;cout调用了拷贝构造函数!n;int GetX()return x;int GetY()return y;void Show()coutx=x,y=yn;第54页/共257页double Distance(Point p1,Point p2)int dx=p1.GetX
34、()-p2.GetX();int dy=p1.GetY()-p2.GetY();return sqrt(dx*dx+dy*dy);Point Mid(Point&p1,Point&p2)int x=(p1.GetX()+p2.GetX()/2;int y=(p1.GetY()+p2.GetY()/2;return Point(x,y);void main()Point p0,p1(8,15);Point p2(p1);/调用拷贝构造函数 Point p3=p1;/等价:Point p3(p1);p1.Show();p2.Show();p3.Show();p3=Mid(p0,p3);coutDi
35、stance(p0,p3)endl;函数Distance(Point,Point)Distance(Point,Point)的形参为类的对象,当执行函数调用distance(p0,p3)distance(p0,p3)时,实参初始化形参,两次调用拷贝构造函数,分别用实参对象p0p0和p3p3初始化形参对象p1p1和p2p2。若函数形参是对象的引用,则调用该函数时,不调用拷贝构造函数,如本例的MidMid函数所示。结果(VC6 with sp6)(VC6 with sp6):调用了拷贝构造函数!调用了拷贝构造函数!x=8,y=15x=8,y=15x=8,y=15x=8,y=15x=8,y=15x=
36、8,y=15调用了拷贝构造函数!调用了拷贝构造函数!8.062268.06226第55页/共257页默认拷贝构造函数:若定义类时未显式定义该类的拷贝构造函数,则编译系统会在编译该类时自动生成一个默认拷贝构造函数。默认拷贝构造函数的功能是把一个已经存在的对象的每个数据成员的值逐个复制到新建立对象对应的数据成员中。例11.12中类Point的拷贝构造函数与默认的拷贝构造函数功能一样,不必显式定义。何时显式定义拷贝构造函数?若类中包含指向动态内存的指针时,用默认的拷贝构造函数初始化对象,将带来严重问题,如例11.13所示。第56页/共257页例11.13 默认拷贝的构造函数。#include#inc
37、ludeclass String char*p;public:String(char*c=0)if(c)p=new charstrlen(c)+1;strcpy(p,c);else p=NULL;String()delete p;void Show()coutstring=pn;void main()void main()String s1(student);String s1(student);String s2(s1);String s2(s1);/A/A s1.Show();s1.Show();s2.Show();s2.Show();第57页/共257页s1.ps1.ps1s1堆内存s2
38、.ps2.ps2s2执行执行A A行语句:调用默认拷贝构造函数,行语句:调用默认拷贝构造函数,用用s1s1对象初始化对象初始化s2s2对象,使对象,使s2s2对象的成对象的成员指针员指针p p与与s1s1对象的成员指针对象的成员指针p p指向同一指向同一片内存。片内存。主函数结束:先撤消主函数结束:先撤消s2s2,s2s2对象释放其对象释放其所指动态内存;其后撤销所指动态内存;其后撤销s1s1对象,但因对象,但因s1s1对象所指动态内存已被对象所指动态内存已被s2s2对象释放,对象释放,造成重复释放同一块动态内存,出现运造成重复释放同一块动态内存,出现运行错误。行错误。定义拷贝构造函数,避免上
39、述错误:定义拷贝构造函数,避免上述错误:String(String&s)String(String&s)if(s.p)if(s.p)p=new charstrlen(s.p)+1;p=new charstrlen(s.p)+1;strcpy(p,s.p);strcpy(p,s.p);else p=0;else p=0;s st tu ud de en n00t t第58页/共257页11.5.5 11.5.5 对象成员与构造函数 对象成员:一个类的对象可做另一个类的数据成员。例如:class Date int year,month,day;public:Date(int y,int m,int
40、 d)year=y;month=m;day=d;class Person char name12;char sex4;Date birthday;/对象成员 public:Person(char*,char*,int,int,int);第59页/共257页对象成员的初始化通过初始化表进行,如:Person:Person(char*n,char*s,int y,int m,int d):birthday(y,m,d)strcpy(name,n);strcpy(sex,s);若未在初始化表中初始化对象成员,则系统自动调用该对象成员的缺省的构造函数来初始化。若类中包含对象成员,则在创建该类的对象时,
41、先调用对象成员的构造函数,初始化相应的对象成员,后执行该类的构造函数,初始化该类的其他成员。如果一个类包含多个对象成员,对象成员的构造函数的调用顺序由它们在该类中的说明顺序决定,而与它们在初始化表中的顺序无关。第60页/共257页例11.14 初始化对象成员。#includeclass Point int x,y;public:Point(int a,int b)x=a;y=b;coutConstructor of class Point is called.n;void Show()coutx=x,y=yendl;第61页/共257页class Rectangle Point p;int l
42、ength,width;public:Rectangle(int l,int w,int a,int b):p(a,b)length=l;width=w;coutConstructor of class Rectangle is called.n;void Show()p.Show();coutlength=length,width=widthendl;void main()Rectangle r(5,4,45,55);r.Show();程序运行结果:Constructor of class Point is called.Constructor of class Point is calle
43、d.Constructor of class Rectangle is called.Constructor of class Rectangle is called.x=45,y=55x=45,y=55length=5,width=4length=5,width=4第62页/共257页11.6 11.6 友元有时需要在对象外部频繁访问对象私有的或保护的数据成员,若通过调用公有成员函数间接访问,由于参数传递、类型检查等都需占用时间,必然降低程序的运行效率。使用友元可在对象外部直接访问对象私有的和保护的数据成员。友元以类的封装性的有限破坏为代价来提高程序的运行效率,应谨慎使用。友元分为:友元函数
44、和友元类。第63页/共257页11.6.1 11.6.1 友元函数友元函数的说明格式:friend FuncName();例11.15 用友元函数的方法计算两点距离。#include#include class Point int x,y;public:Point(int i=0,int j=0)x=i;y=j;int GetX()return x;int GetY()return y;friend double distance(Point&,Point&);普通函数distance()distance()声明为PointPoint类的友元函数。第64页/共257页 double dista
45、nce(Point&p1,Point&p2)int dx=p1.x-p2.x,dy=p1.y-p2.y;return sqrt(dx*dx+dy*dy);void main()Point a(8,15),b(3,7);coutThe distance is:distance(a,b)endl;程序运行结果:The distance is:9.43398The distance is:9.43398友元函数distance()distance()可通过对象名直接访问PointPoint类的对象p1p1和p2p2的私有数据成员x x和y y,提高了程序的效率。第65页/共257页友元函数说明:友元
46、函数说明:友元函数应在类中说明,可放在类的私有、公有或保护部分,友元函数应在类中说明,可放在类的私有、公有或保护部分,效果一样。友元函数体可在类内或类外定义。效果一样。友元函数体可在类内或类外定义。友元函数不是类的成员,不带友元函数不是类的成员,不带thisthis指针,因此必须将对象名指针,因此必须将对象名或对象的引用作为友元函数的参数,并在函数体中用运算符或对象的引用作为友元函数的参数,并在函数体中用运算符“.”来访问对象的成员。如上例中的来访问对象的成员。如上例中的p1.xp1.x。友元函数可直接访问相关类中的所有成员。友元函数可直接访问相关类中的所有成员。一个类的成员函数也可作为另一个
47、类的友元函数,例如:一个类的成员函数也可作为另一个类的友元函数,例如:class Aclass A int f(int f(););class B class B /成员定义成员定义 friendfriend int int A:A:f(f();/);/声明类声明类A A的成员函数的成员函数f()f();/;/是类是类B B的友元的友元在声明这个友元函数时需要在函数名前面加上它的类名和作用域运算符“:”。第66页/共257页11.6.2 11.6.2 友元类若声明A类为B类的友元,则A类的所有成员函数都成为B类的友元函数。有时友元类的使用也是必要的选择。例11.16 友元类。#include#
48、include class Date int year,month,day;public:Date(int y=0,int m=0,int d=0)year=y;month=m;day=d;void display()coutyearmonthday;friend class Person;第67页/共257页class Person char name12;char sex4;Date birthday;public:Person(char*n,int y,int m,int d,char*s)strcpy(name,n);strcpy(sex,s);birthday.year=y;birt
49、hday.month=m;birthday.day=d;void display()coutname:name,sex:sex;cout,birthday:birthday.year.birthday.month.birthday.day静态数据成员名访问静态数据成员时也要注意访问权限。第74页/共257页例11.17 具有静态数据成员的Apple类。#include#includeclass Appleclass Apple float weight;float weight;static int count;/static int count;/静态数据成员的引用性说明 static fl
50、oat total_weight;static float total_weight;public:public:Apple(float=0);Apple(float=0);Apple();Apple();void Show();void Show();第75页/共257页Apple:Apple(float w)Apple:Apple(float w)weight=w;weight=w;count+;count+;total_weight+=weight;total_weight+=weight;coutNumber of apples=countn;coutNumber of apples=