面向对象的妥协

上传人:san****019 文档编号:70851598 上传时间:2019-01-18 格式:PPT 页数:36 大小:218.01KB
返回 下载 相关 举报
面向对象的妥协_第1页
第1页 / 共36页
面向对象的妥协_第2页
第2页 / 共36页
面向对象的妥协_第3页
第3页 / 共36页
面向对象的妥协_第4页
第4页 / 共36页
面向对象的妥协_第5页
第5页 / 共36页
点击查看更多>>
资源描述

《面向对象的妥协》由会员分享,可在线阅读,更多相关《面向对象的妥协(36页珍藏版)》请在金锄头文库上搜索。

1、第6章 面向对象的妥协,授课内容,6.1 封装的破坏友元 6.2 对象机制的破坏静态成员,6.1 封装的破坏友元,6.1 封装的破坏友元,友元可以访问与其有好友关系的类中的任何成员。,友元,友元函数,友元类,如果在本类以外的其他地方定义了一个函数(这个函数可以是不属于任何类的普通函数,也可以是其他类的成员函数),在类体中用friend对其进行声明,此函数就称为本类的友元函数。友元函数可以访问这个类中的任何成员。 如何将普通函数声明为友元函数呢?看下面这个简单的例子:,6.1 封装的破坏友元,6.1.1 友元函数,【例6-1】友元普通函数。,#include using namespace st

2、d; class Clock /声明Clock类 public: Clock(int,int,int); friend void display(Clock ,6.1.1 友元 函数,【例6-1】友元普通函数。,#include using namespace std; class Clock /声明Clock类 public: Clock(int,int,int); friend void display(Clock ,【例6-1】友元普通函数。,Clock:Clock(int h,int m,int s) /构造函数 hour=h; minute=m; second=s; /这是友元函数,

3、形参t是Clock类对象的引用 void display(Clock ,6.1 友元函数,程序运行结果如下: 10:13:56,6.1.1 友元 函数,#include using namespace std; class Date; /对Date类的提前引用声明 class Clock /声明Clock类 public: Clock(int,int,int); void display(Date ,【例6-2】友元成员函数。,class Date /声明Date类 public: Date(int,int,int); friend void Clock:display(Date ,6.1.1

4、 友元 函数,Clock:Clock(int h,int m,int s) / Clock类的构造函数 hour=h; minute=m; second=s; void Clock:display(Date ,6.1.1 友元 函数,int main() Clock t(10,13,56); /定义Clock类对象t Date d(12,25,2004); /定义Date类对象d /调用t的display函数,实参是Date类对象d t.display(d); return 0; ,6.1 友元函数,程序运行结果如下: 12/25/2004 10:13:56,不仅可以将一个函数声明为一个类的“

5、朋友”,而且可以将一个类(例如B类)声明为另一个类(例如A类)的“朋友”。这时B类就是A类的友元类。友元类B中的所有成员函数都是A类的友元函数,可以访问A类中的任何成员。,6.1 封装的破坏友元,6.1.2 友元类,class student; class Teacher public: void assigngrades(Student,6.1.2 友元类,class Student public: friend Teacher; /友元类 protected: int num; string name; float score; ; ,6.1.2 友元类,声明友元类的一般形式为: frie

6、nd 类名; 关于友元,有三点需要说明: (1)友元函数的声明可以出现在类的任何地方(包括在private和public部分),也就是说友元的说明不受成员访问控制符的限制。,6.1.2 友元类,(2)友元关系是单向的而不是双向的,如果声明了B类是A类的友元类,不等于A类是B类的友元类,A类中的成员函数不一定能够访问B类中的成员 (3)友元关系是不能传递的,例如,如果B类是A类的友元类,C类是B类的友元类,并不能说C类就是A类的友元类。,6.1 对象机制的破坏静态成员,在C+中,声明了一个类之后,可以定义该类的多个对象。系统为每个对象分配单独的内存空间。每一个对象都分别有自己的数据成员,不同对象

7、的数据成员各自有其值,互不相干。但是有时我们希望有某一个或几个数据成员为所有对象所共有。这样可以实现数据共享。,6.2 对象机制的破坏 静态成员,我们知道全局变量能够实现数据共享。但是用全局变量的安全性得不到保证,因为在各处都可以自由地修改全局变量的值,很有可能由于某个没注意到的失误,全局变量的值就被修改,导致程序的失败。因此在实际工作中很少使用全局变量。 如果想在同类的多个对象之间实现数据共享,也不要用全局对象,可以用静态成员。静态成员包括静态数据成员和静态成员函数。,6.2 对象机制的破坏 静态成员,静态数据成员是一种特殊的数据成员。它以关键字static开头。例如:,6.2 对象机制的破

8、坏 静态成员,6.2.1 静态数据成员,class Student public: Student(char *name=“no name“); static int stu_count; char name40; ;,静态数据成员在内存中只占一份空间(而不是每个对象都分别为它保留一份空间),它是属于类的,但它被该类的所有对象所共享,每个对象都可以访问这个静态数据成员。静态数据成员的值对所有对象都是一样的。如果改变它的值,则在各对象中这个数据成员的值都同时改变了。这样可以节约空间,提高效率。,6.2.1 静态数据成员,说明: (1)如果只声明了类而未定义对象,则类的一般数据成员是不占内存空间的

9、,只有在定义对象时,才为对象的数据成员分配空间。但是静态数据成员不属于某一个对象,在为对象所分配的空间中不包括静态数据成员所占的空间。静态数据成员是在所有对象之外单独开辟空间。只要在类中定义了静态数据成员,即使不定义对象,也为静态数据成员分配空间,它可以被访问。在一个类中可以有一个或多个静态数据成员,所有的对象共享这些静态数据成员,都可以访问它。,6.2.1 静态数据成员,(2)静态数据成员不随对象的建立而分配空间,也不随对象的撤销而释放(一般数据成员是在对象建立时分配空间,在对象撤销时释放)。静态数据成员是在程序编译时被分配空间的,到程序结束时才释放空间。,6.2.1 静态数据成员,(3)静

10、态数据成员可以初始化,但只能在类体外进行初始化。如: int Student:stu_count=0; /表示对Student类中的静态数据成员初始化 静态数据成员可以初始化语句的一般形式为: 数据类型 类名:静态数据成员名=初值; 不必在初始化语句中加static。,6.2.1 静态数据成员,(4)静态数据成员既可以通过对象名访问,也可以通过类名来访问。,6.2.1 静态数据成员,【例6-3】 访问静态数据成员。,#include using namespace std; #include class Student public: Student(char *name=“ no name“

11、); Student(); static int stu_count; char name40; ;,6.2.1 静态数据成员,【例6-3】 访问静态数据成员。,#include using namespace std; #include class Student public: Student(char *name=“ no name“); Student(); static int stu_count; char name40; ;,Student:Student (char *pname) strcpy(name ,pname); stu_count+; /每创建一个对象,学生人数加1

12、 Student:Student () stu_count-; /每释放一个对象,学生人数减1 /对静态数据成员stu_count初始化 int Student:stu_count=0;,6.2.1 静态数据成员,int main() Student s1; couts1.stu_countendl; Student s2; couts2. stu_count endl; coutStudent:stu_count endl; return 0; ,程序运行结果如下: 1 2 1,6.2.1 静态数据成员,与静态数据成员不同,静态成员函数的作用不是为了对象之间的沟通,而是为了能处理静态数据成员

13、。,6.2 对象机制的破坏 静态成员,6.2.2 静态成员函数,【例6-4】 静态成员函数访问静态数据成员的例子。,#include using namespace std; #include class Student /声明Student类 public: Student(char *name=“no name“); Student(); static int getcount() return stu_count; private: static int stu_count; char name40; ;,6.2.2 静态成员函数,Student:Student (char *pname

14、) strcpy(name ,pname); stu_count+; /每创建一个对象,学生人数加1 Student:Student () stu_count-; /每销毁一个对象,学生人数减1 int Student:stu_count=0;,6.2.2 静态成员函数,int main() Student s1; couts1.getcount()endl; Student s2; couts2.getcount()endl; coutStudent:getcount()endl; return 0; ,6.2.2 静态成员函数,6.2.2 静态成员函数,和静态数据成员一样,静态成员函数是类

15、的一部分,而不是对象的一部分。如果要在类外调用公用的静态成员函数,可以用类名和域运算符“:”,也允许通过对象名调用静态成员函数。如: Student:getcount(); / 用类名调用静态成员函数 s1.getcount(); / 用对象名调用静态成员函数 但这并不意味着此函数是属于对象s1的,而只是用s1的类型而已。,6.2.2 静态成员函数,说明: (1)静态成员函数不能默认访问本类中的非静态成员。当调用一个对象的成员函数(非静态成员函数)时,系统会把该对象的起始地址赋给成员函数的this指针。而静态成员函数并不属于某一对象,它与任何对象都无关,因此静态成员函数没有this指针。既然它没有指向某一对象,就无法对一个对象中的非静态成员进行默认访问(即在访问数据成员时不指定对象名)。 可以说,静态成员函数与非静态成员函数的根本区别是:非静态成员函数有this指针,而静态成员函数没有this指针,因而决定了静态成员函数不能默认访问本类中的非静态成员。,6.2.2 静态成员函数,说明: (2)静态成员函数可以直接访问本类中的静态数据成员,因为静态成员同样是属于类的,可以直接访问。在C+程序中,静态成员函数主要用来访问静态

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

当前位置:首页 > 高等教育 > 大学课件

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号