1 / 36

第十一讲 类与对象(二)

第十一讲 类与对象(二). 11.1 类的静态成员 11.2 类的常量成员 11.3 友元 11.4 类之间的关系 11.5 类中运算符重载. 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载. 由关键字 static 修饰的类成员称为类的 静态成员 。. 特点是不管这个类有多少个对象,但其静态成员在 内存 中 只有一个副本 ,这个副本被该类的全体对象共享。. 静态成员包括 静态数据成员 (成员变量)和 静态函数成员 (成员函数)。. 11.1 类的静态 成员

purity
Download Presentation

第十一讲 类与对象(二)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 第十一讲 类与对象(二) 11.1 类的静态成员 11.2 类的常量成员 11.3 友元 11.4 类之间的关系 11.5 类中运算符重载

  2. 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 由关键字static修饰的类成员称为类的静态成员。 特点是不管这个类有多少个对象,但其静态成员在内存中只有一个副本,这个副本被该类的全体对象共享。

  3. 静态成员包括静态数据成员(成员变量)和静态函数成员(成员函数)。静态成员包括静态数据成员(成员变量)和静态函数成员(成员函数)。 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 静态数据成员为该类全体对象共享。使用静态数据成员之前,必须在类说明体外对静态数据成员进行定义(仅执行一次): 格式:<类型><类名>::<静态数据成员>=<初值> 当使用<对象名>.<静态数据成员名>时,<对象名>和<类名>作用相同

  4. 例1:静态数据成员的实例 #include<iostream.h> //P206 class point { private: static float xcoord, ycoord; public: float getx() {return xcoord} //… } void main (void) { point p, q; //… } 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 由于xoord是类point的静态数据成员,p和q是point的对象,则在任何情况下p.getx()和q.getx()永远同时取相同值

  5. 例2:静态数据成员的实例 #include<iostream.h> //P206 class point { //… public: static float xcoord, ycoord; float getx() {return xcoord} //… } void main (void) { point p, q; //… } 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 当xoord是公开静态数据成员时,p.getx(),q.getx()和point.getx()等价。

  6. 静态函数成员 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 静态函数成员和一般函数成员的主要区别是没有this指针,因此通常只处理类的静态数据成员值或者程序的全局变量。 当使用静态函数成员访问类中非静态成员时,必须借助对象名或者指向对象的指针的函数参数。

  7. 例3:静态函数成员的实例 #include<iostream.h> //P206 class point { static float xcoord, ycoord; public: static float gety(void) {return ycoord;} //… } void main (void) { point p, q; cout<<p::gety(); //… } 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 由于ycoord是静态数据成员,所以p::gety()的执行和返回值都是确定的。

  8. 例4:静态函数成员的实例 #include<iostream.h> //P206 class point { float xcoord, ycoord; public: static float gety(void) {return ycoord;} //… } void main (void) { point p, q; cout<<p::gety(); //… } 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 由于ycoord不是静态数据成员,所以p::gety()将无确切含义。

  9. 例5:静态函数成员的实例 #include<iostream.h> //P206 class point { float xcoord, ycoord; public: static float gety (point &ob) {return ob.ycoord;} //… } void main (void) { point p, q; cout<<point::gety(p); //… } 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 利用静态函数成员gety()得到点p的Y轴坐标

  10. 使用关键字const修饰的类中成员被称为常量成员。常量成员包括常量数据成员和常量函数成员。使用关键字const修饰的类中成员被称为常量成员。常量成员包括常量数据成员和常量函数成员。 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 常量数据成员 常量数据成员在声明时不能被直接赋实值;而只能在声明类对象时,通过构造函数中的成员初始化列表来赋初值。对象初始化结束后,常量数据成员的值不能再被修改。

  11. 构造函数 例6:常量数据成员的实例 class CC { int i; const int c1; //私有常量数据成员 public: const int c2; //公有常量数据成员 /*成员初始化列表c1(a),c2(b)将实参a与b的值赋给c1和c2*/ CC(int a, inb): c1(a),c2(b); i=c1; }; …} 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载

  12. /*在类说明体外说明CC类对象*/ CC cobj(4,7); 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 cobj的3个数据成员 cobj.c1 4 (不可改变) cobj.c2 7 (不可改变 ,可在类外被引用) cobj.i 4 (私有数据成员,只能被类本身的成员函数改变)

  13. 常量函数成员 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 常量函数成员说明格式如下: <类型说明符><函数名>(参数表) const; const是函数类型的一部分。此外,在该函数的实现部分也要加const关键字。 常量函数成员只能读取相应对象的内容,但不能修改。

  14. 例7:常量函数成员的实例 class CC { //P228 int me; public: int readme() const {return me;} //常量函数成员 void writeme (int i) {me=i;} … }; 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 若常量函数成员中出现对该对象的任何写入或者修改将对系统检查视作出错。

  15. 常量函数成员的作用 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 当函数体规模较大,结构较复杂时为避免出现成员函数对对象内容进行错误修改,通常会将成员函数声明为常量函数成员,这就是使用常量函数成员的主要作用。

  16. 友元概念为C++语言所特有,一般在类说明体中出现,使用关键字friend。友元概念为C++语言所特有,一般在类说明体中出现,使用关键字friend。 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 (1)当friend出现在函数说明语句之前,则该函数是该类的友元函数。 (2) 当friend出现在类名B(位于类A的说明体中)之前,则类B是类A的友元类。

  17. 例8:友元函数和友元类的实例。 class A { … friend int f (int a);//友元函数 … friend class B; //友元类 … }; 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载

  18. 友元函数 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 • 不能理解为类的函数成员; • 友元函数定义既可以在类说明体内,也可以类说明体之外。 • 友元函数虽不是类的函数成员,当有权访问和调用类的所有私有成员和保护成员。

  19. 友元函数和一般成员函数的区别 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 友元函数必须在参数表中显式地列出参与运算的全部运算分量(如类对象)。友元函数的调用不通过类对象。 成员函数总是以当前调用者对象为隐式的第一运算分量,当运算涉及的运算对象多于一个时,才在参数表中显式地列出。成员函数调用时必须通过类对象。

  20. 友元类 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 • 在类A中说明的友元类B: • B可能是和A无关的一个类。 • B要在A的类说明体之外说明。 • B的任意函数成员都有权访问和调用A的所有数据成员。

  21. 友元类具有“单方向”和“不传递”等特点。 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 单方向:若claA具有友元类claB,并不意味着claB也具有友元类claA。 不传递:若claA具有友元类claB,claB具有友元类claC,并不意味着从claC可以直接存取claA的私有成员。

  22. 友元的作用 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 封闭和隐藏是面向对象程序设计的主要特征,C++语言也应具有这些特征。 C++语言使用友元在局部打破封装和隐藏特性。 友元概念类似于goto语句,不宜多用。

  23. 例9: 复数类complex中的友元函数。(P230-231) 通过定义友元函数addCom和outCom来操作类complex的私有数据成员。 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载

  24. C++语言中类之间主要有四种联系方式: 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 (1) 一个类的对象作为另一个类的成员。 (2) 一个类的成员函数作为另一个类的友元函数。 (3) 一个类的定义包含在另一个类的说明体中,即类的嵌套。 (4) 一个类作为另一个类的派生类。 上节内容 下章内容

  25. 11.4.1 类的对象成员 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 通过类说明体中的对象声明,可以指定类的数据成员是其它类的对象。这是一种最简单的类对象包含关系。 类说明体中的对象声明不直接和对象的创建与初始化相联系,而是随所在类对象的创建同时创建。

  26. 例10: 类的对象成员的实例(P233) class pixel { int x,y ; public: pixel() {x=0;y=0;} pixel(int x0, int y0) {x=x0; y=y0; } } class line { pixel start, end; //声明pixel的对象 int color; public: line(int sx, int sy, int ex, int ey, int col): start(sx,xy), end(ex,ey) {color=col;}; void main (void) {line line1(20,20,100,20,2), line2(20,20,20,100,1)} 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 在line的构造函数中,通过成员初始化符表把参数传到对象成员的构造函数中。 在程序中创建line类的对象时,必须同时创建pixel类的两个对象。

  27. 成员初始化符表的格式: 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 :<成员初始化符>,…,<成员初始化符> 成员初始化符: <对象成员><初值表> 当类中含有对象成员时,类的构造函数应包含成员初始化符表,负责为类中所含各对象成员进行初始化。

  28. 当定义一个含有对象成员的类对象时,系统调用其构造函数。当定义一个含有对象成员的类对象时,系统调用其构造函数。 首先,按照初始化符表依次执行各对象成员的构造函数,完成对它们的初始化。 其次,执行本类的构造函数体。 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 系统调用本类析构函数时的执行顺序和上述顺序相反。

  29. 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 除了声明类的对象成员之外,将指向对象的指针作为类的成员也是实现类对象包含关系的常用方法。此时,指针是类的一般数据成员,因此不用在类的构造函数中加入成员初始化符表,可以直接在构造函数中完成初始化。

  30. 11.4.2 类的嵌套 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 所谓类的嵌套指的是一个类的说明包含在另一个类的说明。 应尽量避免使用类的嵌套!

  31. 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 在自定义类中,可以通过两种方法实现运算符重载: (1) 以类的公有成员函数方式; (2) 以类的友元方式;

  32. (1)以类的公有成员函数方式 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 • 类成员函数可以处理与使用本类的私有成员。 • 总以当前调用者对象(*this)作为该成员函数的隐式第一运算分量。如果运算涉及多个运算对象,则须在参数表中显式列出其余运算对象。

  33. (2)以类的友元方式 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 • 友元函数可以处理与使用本类的私有成员。 • 所有运算分量必须显式地在参数表中列出,并且这些运算分量中至少有一个用于说明该友元的类或是对该类的引用。

  34. 两点说明: (1)一般来说,单目运算符重载常使用类的成员函数方式;而双目运算符重载常使用类的友元函数方式。 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 (2) 运算符重载后,优先级、运算顺序(结合性)和运算分量个数都必须与系统中的原运算符相一致,而且不可自创新的运算符。

  35. 11.1 类的静态 成员 11.2 类的常量 成员 11.3 友元 11.4 类之间的 关系 11.5 类中运算 符重载 课堂自习 P238 7.8.2 节。

  36. 作 业 思考题: 11, 16, 22 (书面) 练习题: 7, 8 (上机)

More Related