C++知识点集中讲解

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

类及其相关概念1类的定义类是一种用户自定义的数据类型,它的一般定义格式如下:class类名{private:私有数据成员和成员函数;protected:保护数据成员和成员函数;public:公有数据成员和成员函数;}各个成员函数的实现;类定义2例:classRoom{private:introom_no;public:voidset(intinvalue){room_no=invalue;}intget_value(){returnroom_no;}};类定义3类的成员函数也可以另外定义,而在类定义时给出函数头。上例的成员函数可说明如下:voidRoom::set(intinvalue){room_no=invalue;}intRoom::get(){returnroom_no;}另外一种方式4同一个类的所有对象共享数据项只会为整个类创建一个静态数据项只在类的内部可见生命周期贯穿整个程序应该在main()程序开始之前创建并初始化staticdata_typevariable;静态成员数据5如果将一个静态成员声明为类的私有成员,则非成员函数不能访问它是类的全局数据不是对象的一部分,没有this指针更多内容6classalpha{private:staticintcount;//静态数据public:alpha()//构造函数{count++;}staticvoiddisplay_count()//静态成员函数{coutcount;coutendl;}};intalpha::count=0;intmain(){//在创建任何对象之前alpha::display_count();alphaobj1,obj2,obj3;//在创建了三个对象之后alpha::display_count();return0;}静态成员函数示例7嵌套类和局部类在一个类中定义的类称为嵌套类,定义嵌套类的类称为外围类。在一个函数体内定义的类称为局部类。8嵌套类classA{public:classB{public://…;private://…;};voidF();private:intm_a;}嵌套类类9局部类voidA(){classB{public://…;private://…;};}函数局部类10成员函数指针11成员函数指针•成员函数指针首先必须被绑定在一个对象或者一个指针上才能得到被调用对象的this指针•然后才调用指针所指的成员函数12成员函数指针的声明要求扩展的语法•它要考虑类的类型•对指向类数据成员的指针也是这样•考虑Screen类的成员height的类型,–它的完整类型是short型的Screen类的成员,–指向_height的指针的完整类型是指向short型的Screen类的成员的指针,这可以写为shortScreen::*–指向short型的Screen类的成员的指针的定义如下•shortScreen::*ps_Screen;ps_Screen可以用_height的地址初始化如下:shortScreen::*ps_Screen=&Screen::_height;13•使用typedef可以使成员指针的语法更易读,例如下面的类型定义Screen&(Screen::*)()也就是指向Screen类成员函数的一个指针,该函数没有参数,返回Screen类对象的引用•它可以被下列typedef定义Action所取代typedefScreen&(Screen::*Action)();Actiondefault=&Screen::home;Actionnext=&Screen::forward;14模板语法15函数模板templateclassT,classDTmax(Ta,Db){return(ab)?a:b;}16类模板与模板类classINTEGER{intitem;public:INTEGER(int);voidset_item(int);intget_item();};17voidmain(){INTEGERObj(20);Obj.set_item(120);Obj.get_item();}18classREAL{floatitem;public:REAL(float);voidset_item(float);floatget_item();};19voidmain(){REALObj(2.0);Obj.set_item(12.0);Obj.get_item();}20templateclassTclassTemClass{Titem;public:TemClass(T);voidset_item(T);Tget_item();};21voidmain(){TemClassintObjint(20);TemClassfloatObjfloat(2.5);TemClasscharObjchar(‘?A’¡¥);Objint.set_item(120);Objchar.get_item();}22构造函数和析构函数231派生类两构函数的执行顺序•每个类都有显式或隐式的构造函数和析构函数。•派生类中有一个隐含的基类对象,如何对这个对象进行初始化或销毁?•派生类中基类的隐含对象处在派生类任何成员之前。–当创建派生类对象时,先执行基类的构造函数,然后执行派生类自己的构造函数;析构函数则依照相反顺序执行。•析构函数不带参数,一般用户不用处理基类的析构函数。242派生类两构函数的构造规则•当基类的构造函数没有参数或没有显式定义时–派生类可以不向基类隐含对象传递参数,甚至也可以不定义构造函数。–派生类不继承基类的构造函数和析构函数。•当基类含有带参数的构造函数时,派生类必须定义构造函数。–格式:子类构造函数名(参数表):父类构造函数名(参数表){//……}25派生类所不能继承父类的262两构函数的构造规则(续)•当派生类含有成员对象时:基类隐含对象派生类成员对象基类构造函数对象成员构造函数派生类构造函数派生类对象的结构构造函数的执行顺序析构函数的执行顺序派生类析构函数对象成员析构函数基类析构函数27多重继承281多重继承的声明(续)注意:多重继承有二义性的问题在上面的base1,base2中若都有公有成员函数f(),那么用derive的对象使用f()时,是谁的f()呢?classderive:publicbase1,protectedbase2{};classz:publicx,y{public:intg(){f();}}classx{public:intf();}classy{public:intf();}x:://改正293虚基类•为何使用虚基类:当引用派生类d的成员时,首先在派生类d自身的域中寻找此成员,若没有则到它的基类中寻找,依次上溯。如果派生类d是由多个基类(b1,b2)派生出来的,而这些基类又有一个共同的基类B,则在派生类d中访问B的成员时,就会产生二义性。b1b2deriveBB引入虚基类就能解决此二义性问题!!303虚基类(续)•虚基类的使用:不难理解,若上例中类B只存在一个拷贝时,就没有问题了。把类B在派生时声明为“虚”,则原来的继承关系变为下图。•做法:从类B派生时,在其前+“virtual”关键字。classb1:virtualpublicBclassb2:virtualpublicBb1b2deriveB31赋值兼容规则•在继承实现的类层次中,基类更抽象,它包含了其派生类的共性(外延更广)•赋值兼容规则——需要基类对象的任何地方都可以用公有派生类对象来替代•具体情况:1)可以用派生类对象给基类对象赋值,如Baseb;Derived;b=d;32赋值兼容规则(续)2)可以用派生类对象来初始化基类对象的引用,如Derivedd;Base&br=d;3)可以把派生类对象的地址赋值给指向基类的指针,如:Derivedd;Base*bpt=&d;4)可以把指向派生类对象的指针赋值给指向基类对象的指针,如:Derived*dpt;Base*bpt=dpt;33赋值兼容规则(续)•说明:1)基类对象指针可以指向其公有派生类的对象,但不能指向其私有派生类的对象2)不能将一个派生类对象指针指向基类的对象3)声明为指向基类对象的指针,当其指向公有派生类时,只能直接使用从基类继承过来的成员,不能直接使用派生类中的成员341运算符重载•实质:一种特殊的函数重载•作用:扩展了C++的类型机制•分为一般运算符重载(友元)和类成员运算符重载•一般格式:返回类型operator运算符名(参数表){//……}351运算符重载(续)•可以重载的运算符单目:-+!~++--等双目:+-*/%等其他:[]()=newdelete等•不可以重载的运算符:*-::?:#362一般运算符重载示例classcomplex{doublereal;doubleimag;public:complex(doubler=0.0,doublei=0.0){real=r;imag=i;}doublegetReal(){returnreal;}doublegetImag(){returnimag;}friendcomplexoperator+(complex,complex);};372一般运算符重载示例(续)complexoperator+(complexo1,complexo2){complextemp;temp.real=o1.real+o2.real;temp.imag=o1.imag+o2.imag;returntemp;}voidmain(){complexc1(1.0,2.0),c2(3.0,4.0),t;t=c1+c2;//operator+(c1,c2);}384调用方式•调用方式可以象C运算符的使用:complexa,b,c;c=a+b;也可以象函数那样使用:c=operator+(a,b);c=a.operator+(b);或者c.operator=(a.operator(b));39虚函数402虚函数的定义和使用(续)//虚函数示例——比较抽象的类ShapeclassShape{protected:inttype;public:Shape(intt=0){type=t;}virtualintType(){returntype;}//虚函数virtualvoidDraw(){coutShapeDrawendl;}};412虚函数的定义和使用(续)•带有虚函数类对象的内存结构比如:Shapesp;pvtabletypeTypeDrawType函数的代码Draw函数的代码其中,pvtable是虚函数表指针,如果该类没有虚函数,则其对象没有pvtablesp虚函数表虚函数代码423继承中的虚函数(续)//比较抽象的类ShapeclassShape{protected:inttype;public:Shape(intt=-1){type=t;}intType(){returntype;}//定义了两个虚函数virtualvoidDraw(){cout“ShapeDraw\n”;}virtualdoubleArea(){return0.0;};};433继承中的虚函数(续)//点类PointclassPoint:publicShape{protected:intx,y;public:Point(inta=0,intb=0):Shape(0){x=a;y=b;}virtualvoidDraw()//虚函数{cout“PointDrawendl;}};443继承中的虚函数(续)//圆类CircleclassCircle:publicPoint{private:intr;public:Circle(inta,intb,intc):Point(a,b){type=2;r=c;}virtualvoidDraw()//虚函数{cout“CircleDrawendl;

1 / 62
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功