c程序设计(part2).ppt

上传人:wuy****n92 文档编号:70101811 上传时间:2023-01-16 格式:PPT 页数:78 大小:438.50KB
返回 下载 相关 举报
c程序设计(part2).ppt_第1页
第1页 / 共78页
c程序设计(part2).ppt_第2页
第2页 / 共78页
点击查看更多>>
资源描述

《c程序设计(part2).ppt》由会员分享,可在线阅读,更多相关《c程序设计(part2).ppt(78页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、C+程序设计(part 2)OOPnWhatnnon-OO Solution#include#define STACK_SIZE 100struct Stack int top;int bufferSTACK_SIZE;void main()Stack st1,st2;st1.top=-1;st2.top=-1;int x;push(st1,12);pop(st1,x);bool push(Stack&s,int i)if (s.top=STACK_SIZE-1)printf(“Stack is overflow.n”);return false;else s.top+;s.buffers.t

2、op=i;return true;bool pop(Stack&s,int&i)if (s.top=-1)printf(“Stack is empty.n”);return false;else i=s.buffers.top;s.top-;return true;st1.buffer2=-1;st2.buffer2+;_OOPnOO Solution#include#define STACK_SIZE 100class Stack private:int top;int bufferSTACK_SIZE;public:Stack()top=-1;bool push(int i);bool p

3、op(int&i);void main()Stack st1,st2;int x;st1.push(12);st1.pop(x);bool Stack:push(int i);if (top=STACK_SIZE-1)cout “Stack is overflow.n”;return false;else top+;buffer top=i;return true;bool Stack:pop(int&i)if (top=-1)cout “Stack is empty.n”;return false;else i=buffer top;top-;return true;#include#def

4、ine STACK_SIZE 100struct Stack int top;int bufferSTACK_SIZE;void main()Stack st1,st2;st1.top=-1;st2.top=-1;int x;push(&st1,12);pop(&st1,x);Xbool push(Stack*const this,int i)bool pop(Stack*const this,int&i)this-this-this-this-this-this-this-this-st1.buffer2=-1;EncapsulationInformation HiddingOOPnConc

5、eptsnProgramObject1+Object2+ObjectnnObject:Data+OperationnMessage:function callnClassnObject-OrientednObject-BasednOnly Provide EncapsulationnWithout InheritancenAda,etcOOPnWhyn评价标准nEfficency of DevelopmentEfficency of DevelopmentnQualityQualitynExternalExternal Correctness、Efficiency、Robustness、Rel

6、iabilityReliabilityUsabilityUsability、ReusabilityReusabilitynInternalInternal Readability、Maintainability、PortabilityHUIUX产品在规定的条件下和规定的时间内完成规定功能的能力产品在规定的条件下和规定的时间内完成规定功能的能力(概率度量:可靠度)概率度量:可靠度)需求需求架构设计架构设计构建模式构建模式代码代码测试用例测试用例项目组织结构项目组织结构OOPnAdvantages 提高提高开发效率开发效率和和软件质量软件质量n更高层次的抽象数据抽象n数据封装n更好的模块化支持(高

7、内聚、低耦合)n软件复用(部分重用)n对需求变更具有更好的适应性C+vs Java类n类n定义 class ;n组成n成员:成员变量、成员函数n成员变量:在类定义中给出的是声明n成员函数:在类定义中给出的是定义或声明n类成员的访问控制描述类class TDate public:void SetDate(int y,int m,int d);int IsLeapYear();void Print();private:int year,month,day;类定义不完整类n成员变量n声明 在类定义中对成员变量的说明是声明n不能赋值 在类定义中声明成员变量时不能初始化n引用或指针类型成员变量类clas

8、s A;class B A a;/Error B b;/Error A *p;/OK B *q;/OK A&aa;/OK B&bb;/OK 类型还未定义/未定义完全 只能声明成指针或引用类n成员函数n在类定义中定义成员函数(inline)class TDate public:void SetDate(int y,int m,int d)year=y;month=m;day=d;int IsLeapYear()return(year%4=0&year%100!=0)|(year%400=0);private:int year,month,day;类n在类定义外定义成员函数class TDate

9、public:void SetDate(int y,int m,int d);void Print();private:int year,month,day;void TDate:SetDate(int y,int m,int d)year=y;month=m;day=d;void TDate:Print()coutyear.month.dayendl;a.ha.cpp类n成员函数的重载 遵循一般函数的重载规则class A public:void f();int f(int i);double f(double d);void main()A a;a.f();a.f(1);a.f(1.0);

10、类n对象n属性和行为的封装体n类的实例,属于值的范畴 类属于类型范畴,用于描述对象的属性构造函数n对象的初始化n描述n与类同名、无返回类型n自动调用,不可直接调用n可重载n默认构造函数:无参数的构造函数n系统提供的默认构造函数n当类中未提供构造函数时,编译系统自动提供n参与对象的构造过程n通常定义为 publicn有时也声明为私有的,其作用是限制创建该类对象的范围,即只能在本类和友元中创建该类对象构造函数n构造函数的调用n创建对象时,构造函数将自动被调用,所调用的构造函数在创建对象时指定 class A public:A();A(int i);A(char*p);A a1=A(1);A a1(

11、1);A a1=1;/调A(int i)A a2=A();A a2;/调A(),注意:不能写成:A a2();A a3=A(“abcd”);A a3(“abcd”);A a3=“abcd”;/调A(char*)A a4;/调用a0、a1、a2、a3的A()A b5=A(),A(1),A(abcd),2,xyz“;成员初始化表n成员初始化表n定义构造函数时,函数头和函数体之间可以加入一个对数据成员进行初始化的表,用于对数据成员进行初始化 class A int x;const int y;int&z;public:A():y(1),z(x),x(0);成员初始化表class A int m;pu

12、blic:A()m=0;A(int m1)m=m1;class B int x;A a;public:B()x=0;B(int x1)x=x1;B(int x1,int m1):a(m1)x=x1;void main()B b1;/调用调用B:B()和和A:A()B b2(1);/调用调用B:B(int)和和A:A()B b3(1,2);/调用调用B:B(int,int)和和A:A(int)成员初始化表n在构造函数中尽量使用成员初始化表取代赋值动作nconst 成员/reference 成员/对象成员n效率高n数据成员太多时,不采用本条准则n降低可维护性成员初始化表n成员初始化表中的声明次序n

13、成员初始化的次序取决于它们在类定义中的声明次序,与它们在成员初始化表中的次序无关n减轻编译系统的负担n注意类成员定义的次序class CString char *p;int size;public:CString(int x):size(x),p(new charsize);?析构函数n析构函数n()n对象消亡时,系统自动调用class String char*str;public:String()str=NULL;String(char*p)str=new charstrlen(p)+1;strcpy(str,p);String()delete str;int length()return

14、strlen(str);char get_char(int i)return stri;Java:finalize()RAII vs GCResource Acquisition Is Initialization析构函数 void set_char(int i,char value)stri=value;char&char_at(int i)return stri;char*get_str()return str;char*strcpy(char*p)delete str;str=new charstrlen(p)+1;strcpy(str,p);return str;String&strc

15、py(String&s)delete str;str=newcharstrlen(s.str)+1;strcpy(str,s.str);return*this;char*strcat(char*p);String&strcat(String&s);拷贝构造函数nCopy Constructorn创建一个对象时,用另一个同类的对象对其初始化n自动调用 class A int x,y;char *p;public:A();A(const A&a);/拷贝构造函数,const可有可无拷贝构造函数和n三种情况将调拷贝构造函数ncase1A a;A b=a;ncase2f(A a);.A b;f(b);

16、拷贝构造函数ncase3 A f()A a;return a;.f();n如果类定义中没有给出拷贝构造函数,则编译系统提供一个默认拷贝构造函数n默认拷贝构造函数的行为n逐个成员初始化(member-wise initialization)n如果相应的类有对象成员,则该定义是递归的拷贝构造函数class string char*p;public:string(char*str)p=new charstrlen(str)+1;strcpy(p,str);string()delete p;string s1(“abcd”);string s2=s1;abcdpps1s2string:string(c

17、onst string&s)p=new charstrlen(s.p)+1;strcpy(p,s.p);deep copy悬挂指针何时需要copy constructor?abcd动态对象n动态对象n在堆(Heap)中创建的对象称为动态对象nnew/deleten单个动态对象的创建与撤消 class A public:A();A(int);为什么要引入new、delete操作符?constructor/destructor动态对象A*p,*q;p=new A;n 在程序的堆中申请一块大小为sizeof(A)的空间n调用A的默认构造函数对该空间上的对象初始化n返回创建的对象的地址并赋值给pq=n

18、ew A(1);nn调用A的另一个构造函数 A:A(int)ndelete p;n调用p所指向的对象的析构函数n释放对象空间 delete q;动态对象np=(A*)malloc(sizeof(A)free(p)malloc 不调用构造函数 free 不调析构函数nnew 操作符n自动分配足够的空间n自动返回指定类型的指针n可以重载 动态对象数组n动态对象数组的创建与撤消A*p;p=new A100;delete p;n注意n不能显式初始化,相应的类必须有默认构造函数ndelete中的不能省Const 成员nconst 成员nconst 成员变量n在成员变量的声明中加上const,则表示是常量

19、class A const int x;n初始化放在构造函数的成员初始化表中进行class A const int x;public:A(int c):x(c)Const 成员nconst 成员函数class A int x,y;public:void f();const A a;na.f()合法?na是常量,在程序中不应改变a的值(改变a的成员变量的值)n如果A:f中没有改变a的成员变量的值,则是合法的,否则是不合法的Const 成员n编译程序往往无法知道函数f中是否改变了a的成员变量的值n为了安全,编译程序认为a.f()不合法na.f()合法n在A:f中不能改变a的成员变量的值n在f的定义

20、和声明处显式地指出之class A void f()const;Const 成员nconst 成员函数不能修改成员变量的值n成员函数加上const 修饰符的作用n调用点:告诉编译器该成员函数不不会会改变对象成员变量的值 n定义点:告诉编译器该成员函数不不应应该该改变对象成员变量的值静态成员n静态成员n类刻划了一组具有相同属性的对象n对象是类的实例n类中声明的成员变量属于实例化后的对象,有多个拷贝n问题:同一个类的不同对象如何共享变量?n如果把这些共享变量定义为全局变量,则缺乏数据保护,静态成员n静态成员变量class A int x,y;static int shared;.;int A:sh

21、ared=0;A a,b;n类定义中声明的静态变量被该类的对象所共享n类的静态成员变量只有一个拷贝n静态变量也遵循类的访问控制静态成员n静态成员函数class A static int shared;int x;public:static void f()shared void q()xshared;n静态成员函数只能存取静态成员变量和调用静态成员函数静态成员函数只能存取静态成员变量和调用静态成员函数n静态成员函数也遵循类的访问控制静态成员n静态成员的使用n通过对象使用A a;a.f();n通过类使用A:f();nC+对类也是对象的观点的支持n在一些面向对象程序设计语言(如:Smalltalk

22、)中,把类也看成是对象,其属性由元类(meta class)来描述n类定义中的静态成员就是属于类这个对象静态成员class A static int obj_count;public:A()obj_count+;A()obj_count-;static int get_num_of_obj()return obj_count;int A:obj_count=0;n类A是对象nobj_count:程序运行的某时刻存在的A类对象的数目nget_num_of_obj:获取A类对象的数目的方法示例class singletonprotected:singleton()singleton(const s

23、ingleton&);public:static singleton*instance()return m_instance=NULL?m_instance=new singleton:m_instance;static void destroy()delete m_instance;m_instance=NULL;private:static singleton*m_instance;singleton*singleton:m_instance=NULL;singletonResource Control原则:谁创建,谁归还解决方法:自动归还友元n友元n类外部不能访问该类的private成员

24、n通过该类的public方法n会降低对private成员的访问效率,缺乏灵活性n例:矩阵类(Matrix)、向量类(Vector)和全局函数(multiply),全局函数实现矩阵和向量相乘友元int&element(int i,int j)return*(p_data+i*col+j);void dimension(int&l,int&c)l=lin;c=col;void display()int*p=p_data;for(int i=0;ilin;i+)for(int j=0;jcol;j+)cout *p ;p+;cout endl;class Matrix int *p_data;int

25、 lin,col;public:Matrix(int l,int c)lin=l;col=c;p_data=new intlin*col;Matrix()delete p_data;友元class Vector int *p_data;int num;public:Vector(int n)num=n;p_data=new intnum;Vector()delete p_data;int&element(int i)return p_datai;void dimension(int&n)n=num;void display()int*p=p_data;for(int i=0;inum;i+,p

26、+)cout *p ;cout endl;友元void multiply(Matrix&m,Vector&v,Vector&r)int lin,col;m.dimension(lin,col);for(int i=0;ilin;i+)r.element(i)=0;for(int j=0;jf();func1(b);func2(&b);A:f?B:f?虚函数n前期绑定(Early Binding)n编译时刻n依据对象的静态类型n效率高、灵活性差n动态绑定(Late Binding)n运行时刻n依据对象的实际类型(动态)n灵活性高、效率低n注重效率n默认前期绑定n后期绑定需显式指出virtual虚

27、函数n定义nvirtualclass A public:virtual void f();n动态绑定n 根据实际引用和指向的对象类型n方法重定义虚函数n如基类中被定义为虚成员函数,则派生类中对其重定义的成员函数均为虚函数n限制n类的成员函数才可以是虚函数n静态成员函数不能是虚函数n内联成员函数不能是虚函数n构造函数不能是虚函数n析构函数可以(往往)是虚函数虚函数n后期绑定的实现class A int x,y;public:virtual f();virtual g();h();class B:public A int z;public:f();h();A a;B b;A*p;创建一个虚函数表(

28、vtable)记录所有虚函数入口地址对象的内存空间中含有指针,指向其虚函数表B:fA:gbxyzB_vtablep-f()(*(char*)p-4)(p)axyA:f A:gA_vtable虚函数class A public:A()f();virtual void f();void g();void h()f();g();class B:public A public:void f();void g();B b;A*p=&b;p-f();p-g();p-h();/A:A(),A:f,B:B(),/B:f/A:g/A:h,B:f,A:gclass A public:virtual void f(

29、);void g();class B:public A public:void f()g();void g();B b;A*p=&b;p-f();/b.B:g虚函数n纯虚函数和抽象类n纯虚函数n声明时在函数原型后面加上=0 virtual int f()=0;n往往只给出函数声明,不给出实现n抽象类n至少包含一个纯虚函数n不能用于创建对象n为派生类提供框架,派生类提供抽象基类的所有成员函数的实现class AbstractClass public:virtual int f()=0;虚函数FigureRectangleEllipseLinevirtual display()=0;display

30、displaydisplayFigure*a100;a0=new Rectangle();a1=new Ellipse();a2=new Line();for(int i=0;idisplay();class Button;/Abstract Class class MacButton:public Button;class WinButton:public Button;class Label;/Abstract Class class MacLabel:public Label;class WinLabel:public Label;class AbstractFactory public

31、:virtual Button*CreateButton()=0;virtual Label*CreateLabel()=0;class MacFactory:public AbstractFactory public:MacButton*CreateButton()return new MacButton;MacLabel*CreateLabel()return new MacLabel;class WinFactory:public AbstractFactory public:WinButton*CreateButton()return new WinButton;WinLabel*Cr

32、eateLabel()return new WinLabel;AbstractFactory*fac;switch(style)case MAC:fac=new MacFactory;break;case WIN:fac=new WinFactory;break;Button*button=fac-CreateButton();Label*Label=fac-CreateLabel();抽象工厂模式Abstact Factory虚函数n虚析构函数class B;class D:public B;B*p=new D;?:delete p;class string class B class D:

33、public Bstring name;B*p=new D;?:delete p;虚函数n确定public inheritance,是真正意义的“is_a”关系n不要定义与继承而来的非虚成员函数同名的成员函数class B public:void mf();class D:public B ;D x;B*pB=&x;pB-mf();D*pD=&x;pD-mf();public:void mf();/B:mf/D:mfclass rectangle public:void setHeight(int);void setWidth(int);int height()const;int width(

34、)const;class Square:public rectangle public:void setLength(int);virtualvirtualprivate:void setHeight(int);void setWidth(int);Penguinclass FlyingBirdclass NonFlyingBirdvirtual void fly()error(Penguins cant fly!);void makeBigger(Rectangle&r)int oldHeight=r.height();r.setWidth(r.width()+10);assert(r.he

35、ight()=oldHeight);assert(s.width()=s.height();虚函数n明智地运用private InheritancenImplemented-in-term-ofn需要使用Base Class中的protected成员,或重载virtual functionn不希望一个Base Class被client使用n在软件”设计”层面无意义,只用于软件实现层面class CHumanBeing ;class CStudent:private CHumanBeing ;void eat(const CHumanBeing&h)CHumanBeing a;CStudent

36、b;eat(a);eat(b);/Error虚函数n纯虚函数只有函数接口会被继承n子类必须继承函数接口n(必须)提供实现代码n一般虚函数函数的接口及缺省实现代码都会被继承n子类必须继承函数接口n可以继承缺省实现代码n非虚函数函数的接口和其实现代码都会被继承n必须同时继承接口和实现代码class Shape public:virtual void draw()const=0;virtual void error(const string&msg);int objectID()const;虚函数n绝对不要重新定义继承而来的缺省参数值n静态绑定n效率class Apublic:virtual voi

37、d f(int x=0);class B:public Apublic:virtual void f(int x=1);class C:public Apublic:virtual void f(int);A*p_a;B b;p_a=&b;p_a-f();A*p_a1;C c;p_a1=&c;p_a1-f();对象中只记录虚函数的入口地址多继承n多继承n定义class:,成员表n继承方式npublic、private、protectedn继承方式及访问控制的规定同单继承n派生类拥有所有基类的所有成员多继承BedweightSleep()SetWeight()SofaweightWatchTV(

38、)SetWeight()SleepSofafoldOut()多继承FurnitureweightSetWeight()FurnitureweightSetWeight()BedSleep()SofaWatchTV()SleepSofaFoldOut()Base-ClassDecomposition多继承FurnitureweightSetWeight()BedSleep()SofaWatchTV()SleepSofaFoldOut()Virtual Inheritance多继承n基类的声明次序决定:n对基类构造函数/析构函数的调用次序n对基类数据成员的存储安排n名冲突n:n虚基类n如果直接基类有公共的基类,则该公共基类中的成员变量在多继承的派生类中有多个副本DABCclass A int x;class B:A;class C:A;class D:B,C;多继承n类D拥有两个x成员:B:x和C:xn虚基类n合并class A;class B:virtual A;class C:virtual A;class D:B,C;n注意n虚基类的构造函数由最新派生出的类的构造函数调用n虚基类的构造函数优先非虚基类的构造函数执行

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com