复习.docx
- 文档编号:29195150
- 上传时间:2023-07-21
- 格式:DOCX
- 页数:31
- 大小:23.42KB
复习.docx
《复习.docx》由会员分享,可在线阅读,更多相关《复习.docx(31页珍藏版)》请在冰豆网上搜索。
复习
一、C++的初步知识
函数的重载
重载是用来描述同名函数具有相同或者相似功能,但数据类型或者是参数不同的函数管理操作的称呼。
同一个函数名可以用来代表不同功能的函数,也就是一名多用。
C++的函数如果在返回类型、参数类型、参数个数、参数顺序上有所不同,则认为是不同的。
但重载函数如果仅仅是返回类型不同,则是不够的。
(1分)
函数模板
函数模板就是建立一个通用函数,其函数类型和形参类型不具体指定,用一个虚拟的类型来代表。
template
//
Tmax(Ta,Tb,Tc)//定义一个通用函数,用T作虚拟的类型名
{
if(a
a=b;
if(a a=c; returna; } 模板类型参数没有隐式转换的说法,必须精确匹配。 (1分) 有默认参数的函数 当又有声明又有定义时,定义中不允许默认参数。 如果函数只有定义,则默认参数才可出现在函数定义中。 如果一个函数中有多个默认参数,则形参分布中,默认参数应从右至左逐渐定义。 当调用函数时,只能向左匹配参数。 (1分) 变量的引用 P20例1.12P36练习12、13(3分) New(1分) int*p=newint(100);√ int*p=newint[100];√ int*p=newint;√ int*p=newint[2][3];× 二、类的定义 对象的三大特性: 实现信息隐藏的封装性、实现代码重用的继承性、实现由继承产生的不同类对象对同一消息的不同响应的多态性。 (2分) //例2_1类的定义 #include usingnamespacestd; classMyclass//class后跟类名,一般以大写字母开头,类包含两个成员 { private: //私有的,也可以缺省,即默认的为私有的 inti;//私有数据成员 protected: //保护的 intm;//保护数据成员 public: //公共的 intp;//公共的数据成员 voidset(intx1,intx2,intx3)//公共成员函数,一般情况下,成员函数都是公共的 { i=x1;m=x2;p=x3;//一定要有一个对类中的数据成员初始化的成员函数,这样才有意义 } }; intmain() { Myclassmy;//定义对象my,会为其分配内存空间 my.set(1,2,3);//给对象赋初值 return0; } 说明: 在类中不允许对所定义的数据成员直接进行初始化,所以要通过一个成员函数set来完成。 (1分) 为了类的封装性和信息隐蔽,我们常常将定义与实现分开来,我们在类的定义中只有成员函数的声明,成员函数的定义在类外进行。 //例2_2类的定义,成员函数类中声明,成员函数类外定义,5分 classMyclass { private: inti; protected: intm; public: intp; voidset(intx1,intx2,intx3);//成员函数的声明 }; voidMyclass: : set(intx1,intx2,intx3)//成员函数的类外定义 { i=x1;m=x2;p=x3; } intmain() { Myclassmy; my.set(1,2,3); return0; } 学习了构造函数以后,对数据成员的初始化工作是由构造函数来完成的。 上例用构造函数来实现的话,程序如下。 //例2_3构造函数5分 #include usingnamespacestd; classMyclass { private: inti; protected: intm; public: intp; Myclass(intx1,intx2,intx3)//构造函数 { i=x1;m=x2;p=x3; } }; intmain() { Myclassmy(1,2,3);//注意定义对象的改变 return0; } 说明: (1分) ●构造函数名与类名同名。 ●没有任何返回类型,即使是void也没有。 ●构造函数可以重载 ●定义对象要按构造函数的定义形式给实际参数。 ●例2_1中定义对象时没有给参数,那是因为有一个默认的构造函数是无参的。 如果不定义构造函数,系统会在定义对象时自动调用默认的构造函数。 ●当定义了构造函数以后,默认的构造函数就不存在了,所以在例2_3中不能像在例2_1和2_2中一样定义对象。 对象赋了初值,但我们没有去输出该对象的数据成员的值。 我们来输出试试看。 //例2_4有错程序,类外访问非公有成员 #include usingnamespacestd; classMyclass { private: inti; protected: intm; public: intp; Myclass(intx1,intx2,intx3) { i=x1;m=x2;p=x3; } }; intmain() { Myclassmy(1,2,3); cout< cout< cout< return0; } 运行时会出现如下错误 errorC2248: 'i': cannotaccessprivatememberdeclaredinclass'Myclass' errorC2248: 'm': cannotaccessprotectedmemberdeclaredinclass'Myclass' Cpp1.exe-2error(s),0warning(s) 是什么原因呢? 那是因i是私有的数据成员,只能在类中被访问,到了类外(本例是在mian中)就无法访问了。 同理m是保护的数据成员,也只能在类中被访问,或被继承访问,不能在类外访问。 有什么方法改变上述的情况呢? 方法一: 把要访问的数据成员i和m改为公有的。 这种方法破坏了封装性,是不可取的。 方法二: 定义一个公有的成员函数,这是常用的方法 //例2_5用方法二实现对非公有成员的使用5分 #include usingnamespacestd; classMyclass { private: inti; protected: intm; public: intp; Myclass(intx1,intx2,intx3) { i=x1;m=x2;p=x3; } voiddisplay()//定义了一个公共的成员函数,这样就可以在类外使用了。 { cout< cout< cout< } }; intmain() { Myclassmy(1,2,3); my.display(); return0; } 方法三: 定义可以取到i的公共成员函数和可以取到m的公共成员函数 //例2_6用方法三实现对非公有成员的使用 #include usingnamespacestd; classMyclass { private: inti; protected: intm; public: intp; Myclass(intx1,intx2,intx3) { i=x1;m=x2;p=x3; } intgeti(){returni;} intgetm(){returnm;} }; intmain() { Myclassmy(1,2,3); cout< cout< cout< return0; } 方法四: 定义一个友员函数,这样就可以访问类中的私有成员,虽然破坏了类的封装性,但提高了效率。 友员函数必须有类中用friend声明。 //例2_7用方法四实现对非公有成员的使用 #include usingnamespacestd; classMyclass { private: inti; protected: intm; public: intp; Myclass(intx1,intx2,intx3) { i=x1;m=x2;p=x3; } friendvoiddisplay(Myclassmy); }; voiddisplay(Myclassmy) { cout< } intmain() { Myclassmy(1,2,3); display(my); return0; } 函数可以重载,当然成员函数、构造函数也能重载。 //例2_8构造函数的重载 #include usingnamespacestd; classMyclass { private: inti; protected: intm; public: intp; Myclass(intx1,intx2,intx3)//构造函数1 { i=x1;m=x2;p=x3; } Myclass(intx1,intx2)//构造函数2 { i=x1;m=x2;p=0; } Myclass(intx1)//构造函数3 { i=x1;m=0;p=0; } Myclass()//构造函数4 { i=0;m=0;p=0; } voiddisplay(){cout< }; intmain() { Myclassmy1(1,2,3); my1.display(); Myclassmy2(1,2); my2.display(); Myclassmy3 (1); my3.display(); Myclassmy4; my4.display(); return0; } 上例重载是通过参数个数的不同来区别到底调用的是哪一个构造函数。 上例的构造函数还可以简化,因为函数参数可以设置默认值。 我们可以通过默认值的设置来达到重载的目的。 //例2_9参数有默认值的构造函数,阅读程序4分 #include usingnamespacestd; classMyclass { private: inti; protected: intm; public: intp; Myclass(intx1=0,intx2=0,intx3=0)//可以省缺参数。 设置省缺的参数值为0 { i=x1;m=x2;p=x3; } voiddisplay(){cout< voidseti(intii){i=ii;} intgeti(){returni;} }; intmain() { Myclassmy1(1,2,3); my1.display(); Myclassmy2(1,2); my2.seti(100); cout< my2.display(); Myclassmy3 (1); my3.display(); Myclassmy4; my4.display(); return0; } 运行结果: 1,2,3 100 100,2,0 1,0,0 0,0,0 Pressanykeytocontinue 实际上,如果考虑空间和时间的问题,我们定义类还要考虑以下几个问题。 ●内联函数的使用(inline) ●常成员函数 ●常数据成员 ●常对象 //例: 常对象的定义,常对象只能调用常成员函数3分 #include usingnamespacestd; classBox {public: Box(intl,intw,inth){length=l,width=w,heigth=h;} voiddisplay()const { cout<<"长: "< "< "< } private: intlength,width,heigth; }; intmain() {constBoxB(10,2,3);//常对象只能调用常成员函数 B.display(); return0; } ●指向对象的常指针 将指向对象的指针变量声明为const型,并使之初始化,这样指针值始终保持为初值,不能改变,即其指向始终不变。 Box*constptr1=&B;//定义的常指针,一定要初始化。 (1分) ●静态成员 当成员不属于某一个对象,而是属于整个类时,要定义为静态成员,包括静态数据成员和静态成员函数。 用static来声明。 静态数据成员必须对它进行初始化。 初始化时要在类外;不用再加static了;定义时一定要带上类名: : 静态数据成员可以在类外也可以在类内定义,当在类外定义时,不要再用static。 //例2_10静态数据成员和静态成员函数3分 #include usingnamespacestd; classPoint {public: Point(intxx=0,intyy=0){X=xx;Y=yy;countP++;} ~Point(){countP--;} intGetX(){returnX;} intGetY(){returnY;} staticvoidGetC(){cout<<"Objectid="< private: intX,Y; staticintcountP; }; intPoint: : countP=0;//静态数据成员的初始化 intmain() { Point: : GetC(); PointA(4,5),B[2]={Point(1,2),Point(3,4)},*p[2];//一共建立了几个对象? 1分 //对象数组的正确初始化1分 Point: : GetC(); return0; } 运行结果: Objectid=0 Objectid=3 ●析构函数 是类中特殊的成员函数,当对象撤消时,就会马上被调用,其作用是善后处理。 它没有返回类型,没有参数,不能随意调用,也不能重载。 只是在类对象生命期结束的时候,由系统自动调用。 构造函数不同于析构函数,可以有参数,可以重载。 (1分) //例2_11析构函数 #include usingnamespacestd; classMyclass { private: inti; protected: intm; public: intp; Myclass(intx1=0,intx2=0,intx3=0)//构造函数 { i=x1;m=x2;p=x3;cout<<"构造函数"<<''< } ~Myclass(){cout<<"析构函数"< }; intmain() { Myclass*ptr=newMyclass[2]; delete[]ptr; return0; } 为了说明问题,我们把构造函数和析构函数中用了输出语句,但实际情况下是析构函数是用来释发资源而用的。 ●拷贝构造函数 当类的定义有动态资源分配时,对象之间的赋值就需要自己编写拷贝构造函数。 拷贝构造函数的形式如下: Myclass: : Myclass(constMyclass&k){} 拷贝构造函数在以下3种情况下会被调用: 1)用类的一个已知的对象去初始化该类的另一个正在创建的对象。 2)采用传值调用方式时,对象作为函数实参传递给函数形参。 3)对象作为函返回值。 //例2_12阅读程序4分 classA {public: A(){cout<<"ConstructingA"< }; classMyClass {public: MyClass(intnn=0): n(nn)//要负责构造子对象 {cout<<"Constructing"< MyClass(MyClass&m) {n=m.n; cout<<"Copying"< } private: intn; Aa;//有子对象 }; intmain() {MyClassmyclass1(301),myclass2(myclass1);//复制myclass2会调用拷贝构造函数 return0; } 运行结果: ConstructingA Constructing301 ConstructingA Copying301 ●友元 我们知道类的一大特性就是封装性,在类外是不能访问私有成员的,而有时为了增加效率而不惜牺牲封装性,通过友元来对有好友关系的类中的私有成员进行访问。 友元可以是成员函数也可以是普通函数,还可以是一个类。 //例2_13用友元函数来实现求二点之间的距离5分 #include #include usingnamespacestd; classPoint { public: Point(intX,intY) {x=X;y=Y;} friendfloatDistance(Pointp1,Pointp2); private: intx,y; }; floatDistance(Pointp1,Pointp2) {returnsqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y));} intmain() {Pointp1(1,1),p2(2,2); cout< return0; } ●类模板 ●运算符重载 不是所有的运算符都可以通过重载而被赋予新的含义的。 能够被重载的操作还需遵守以下规则。 (1分) 1、C++不允许用户自己创建新的运算符,只能对已有的C++运算符进行重载。 2、操作个数不变、优先级不变、结合性不变 3、不能有默认的参数 4、重载运算符必须和用户定义的对象一起使用,其参数至少应有一个是类对象或类对象的引用。 也就是说参数不能全是C++的标准类型,以防用户改变了原标准类型的运算性质。 5、重载后的操作符的新意思要与原意一致。 6、基本规则 1)一元操作符可以是不带参数的成员函数或带一个参数的非成员函数。 2)二元操作符可以是带一个参数的成员函数或带两个参数的非成员函数。 3)operator<<、operator>>不能定义为成员函数。 4)重载operator++和operator--时带一个int参数表示后缀,不带参数表示前缀。 //例2_14运算符+和<<的重载8分 classPoint { public: Point(intX,intY) {x=X,y=Y;} friendostream&operator<<(ostream&output,Pointp);//声明 Pointoperator+(Pointp)//operator+的下定义 {returnPoint(x+p.x,y+p.y);} private: intx,y; }; ostream&operator<<(ostream&output,Pointp)//定义 {returnoutput<<'('< intmain() {Pointp1(1,2),p2(3,4); cout< return0; } 三、类的继承与派生 面向对象程序设计的三大特性是封装性、继承性、多态性。 下面讨论类的继承性。 //例3_1定义一个基类Point,再由基类派生一个矩形类。 10分 #include usingnamespacestd; classPoint { protected: intx,y; public: Point(inta,intb) { x=a;y=b; } }; classRectangle: publicPoint { intlength,width; public: Rectangle(inta,intb,intl,intw): Point(a,b)//要负责基类的构造 { length=l;width=w; } intarea() { returnlength*width; } voiddisplay()//在派生类中可以使用基类中的保护成员x,y {cout<<"("< }; intmain() { Rectangler(1,2,3,4); r.display(); } 知道构造函数和析构函数的执行顺序吗? 先构造的后析构,后构造的先析构 //例3_2阅读程序 #include usingnamespacestd; classA { public: A(){cout<<"构造函数A\n";} ~A(){cout<<"析构函数A\n";} }; classB: public
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 复习