欢迎来到三一文库! | 帮助中心 三一文库31doc.com 一个上传文档投稿赚钱的网站
三一文库
全部分类
  • 研究报告>
  • 工作总结>
  • 合同范本>
  • 心得体会>
  • 工作报告>
  • 党团相关>
  • 幼儿/小学教育>
  • 高等教育>
  • 经济/贸易/财会>
  • 建筑/环境>
  • 金融/证券>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 三一文库 > 资源分类 > PPT文档下载
     

    第5章数据的共享与保护.ppt

    • 资源ID:2257001       资源大小:1.22MB        全文页数:120页
    • 资源格式: PPT        下载积分:10
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录   微博登录  
    二维码
    微信扫一扫登录
    下载资源需要10
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    第5章数据的共享与保护.ppt

    第5章 数据的共享与保护,第5章 数据的共享与保护,1、标识符的作用域与可见性 2、对象的生存期 3、类的静态成员(微视频) 4、类的友元 5、共享数据的保护(微视频) 6、多文件结构和编译预处理命令(微视频) 7、综合实例个人银行账户管理程序(微视频) 8、小结,第5章 数据的共享与保护,1、标识符的作用域与可见性 2、对象的生存期 3、类的静态成员(微视频) 4、类的友元 5、共享数据的保护(微视频) 6、多文件结构和编译预处理命令(微视频) 7、综合实例个人银行账户管理程序(微视频) 8、小结,1、标识符的作用域与可见性,作用域 可见性,作用域,作用域是一个标识符在程序正文中有效的区域。 C+中标识符的作用域: 1、函数原型作用域 2、局部作用域(块作用域) 3、类作用域 4、命名空间作用域(文件作用域),1、函数原型作用域,函数原型中的参数,其作用域始于“(“,结束于“)“。 例如,设有下列原型声明: double Area(double radius);,2、局部作用域(块作用域),在块中声明的标识符,其作用域自声明处起,限于块中,例如: void fun(int a) int b(a); cinb; if(b0) int c; ,a的作用域在哪儿?,3、类作用域,类作用域作用于特定的成员名。 类X的成员m具有类作用域,对m的访问方式如下: 如果在X的成员函数中没有声明同名的局部作用域标识符,那么在该函数内可以访问成员m。属于类内访问。 通过表达式x.m或者X:m访问。属于类外访问。 通过表达式prt-m访问。其中prt为指向X类的一个对象的指针。属于类外访问。,4、命名空间作用域(文件作用域),一个大型的程序通常由不同模块构成,不同的模块甚至有可能是由不同人员开发的。不同模块中的类和函数之间可能发生重名,这样就会引发错误。命名空间(namespace)的概念正是为了解决这个问题而提出的。 一个命名空间将不同的标识符集合在一个命名作用域(named scope)内。这样,在不同的命名空间中,即使使用同样的标识符来表示不同的事物,也不会引起命名冲突。,4、命名空间作用域(文件作用域),命名空间的语法形式如下: namespace 命名空间名 命名空间内的各种声明(函数声明、类声明等) 在命名空间内部可以直接引用当前命名空间中声明的标识符,如果需要引用其他命名空间的标识符,需要使用以下语法: 命名空间名:标识符名,4、命名空间作用域(文件作用域),#include namespace mycode void sqrt(); int main() mycode:sqrt(); return 0; namespace mycode void sqrt() std:cout “sqrt called in the mycode namespace“ std:endl; ,运行结果: sqrt called in the mycode namespace,4、命名空间作用域(文件作用域),在标识符前总使用命名空间限定,会显得过于冗长。C+为此提供了using语句的两种形式: using 命名空间名:标识符名; using namespace 命名空间名; 第1种形式将命名空间内的某一指定标识符暴露在当前的作用域内,使得在当前作用域中可以直接引用这个指定的标识符。 第2种形式将命名空间内的所有标识符暴露在当前的作用域内,使得在当前作用域中可以直接引用命名空间内的所有(任何)标识符。,4、命名空间作用域(文件作用域),#include namespace mycode void sqrt() std:cout “sqrt called in the mycode namespace“ std:endl; using namespace mycode; int main() sqrt(); return 0; ,运行结果: sqrt called in the mycode namespace,4、命名空间作用域(文件作用域),C+标准程序库的所有标识符都被声明在std命名空间内,所以: 如果前面的程序使用了 using namespace std; 那么可以直接使用 cin、cout、endl 等标识符。 如果前面的程序没有使用 using namespace std;那么只能这样使用 std:cin、std:cout、std:endl 等标识符。,例5-1 作用域实例,运行结果: i=7 j=6 i=5,#include using namespace std; int i; / 在全局命名空间中的全局变量 namespace Ns int j; / 在 Ns 命名空间中的全局变量 int main() i = 5; / 为全局变量 i 赋值 Ns:j = 6; / 为全局变量 j 赋值 using namespace Ns; / 子块 int i; / 局部变量,局部作用域 i = 7; / 为局部变量 i 赋值 cout “i=“ i endl; / 输出 7 cout “j=“ j endl; / 输出 6 cout “i=“ i endl; / 输出 5 return 0; ,可见性,可见性是从对标识符的引用的角度来看标识符的有效范围。 可见性表示从内层作用域向外层作用域“看”时能看见什么。 如果标识符在某处可见,则就可以在该处引用此标识符。,可见性,作用域可见性的一般规则: 标识符应声明在先,引用在后。 在同一作用域中,不能声明同名的标识符。 在没有互相包含关系的不同的作用域中声明的同名标识符,互不影响。 如果某个标识符在外层中声明,且在内层中没有同一标识符的声明,则该标识符在内层可见。 如果在两个或多个具有包含关系的作用域中声明了同名标识符,则外层标识符在内层不可见。,同一作用域中的同名标识符,在同一作用域内的对象名、函数名、枚举常量名会隐藏同名的类名或枚举类型名。 Clock Clock; Clock.setTime(); 重载的函数可以有相同的函数名。 作用域和可见性的原则不仅适用于变量名,而且也同样适用于其他各种标识符,包括常量名、用户自定义的类型名、函数名、枚举类型的取值等。,第5章 数据的共享与保护,1、标识符的作用域与可见性 2、对象的生存期 3、类的静态成员(微视频) 4、类的友元 5、共享数据的保护(微视频) 6、多文件结构和编译预处理命令(微视频) 7、综合实例个人银行账户管理程序(微视频) 8、小结,2、对象的生存期,对象(包括简单变量)从产生到结束的这段时间就是它的生存期。在对象生存期内,对象(包括简单变量)将保持它的状态(即:数据成员的值),直到它们被更新为止。 对象的生存期分为: 静态生存期 动态生存期,静态生存期,如果对象生存期与程序的运行期相同,则称它具有静态生存期。 在命名空间作用域中声明的对象具有这种静态生存期。 在函数内部声明静态生存期对象,要冠以关键字static 。,例:静态生存期,运行结果: i=5 2 3,#include using namespace std; int i=5; / 命名空间作用域,i具有静态生存期 void print( ) static int j = 1; / 静态局部变量j具有静态生存期 j+; cout j endl; int main( ) cout“i=“iendl; print( ); print( ); return 0; ,动态生存期,块作用域中声明的、没有用static修饰的对象是动态生存期的对象(习惯称局部生存期对象)。 局部生存期对象诞生于声明点时,结束于声明所在的块执行完毕时。,例:动态生存期,运行结果: i=6,a=2 i=6,a=3,#include using namespace std; void fun(); int main() fun(); fun(); return 0; void fun() static int a = 1; / a是静态生存期 int i = 5; / i是动态生存期 a+; i+; cout “i=“ i “,a=“ a endl; ,例5-2 变量的生存期与可见性,#include using namespace std; int i=1; / i 为全局变量,具有静态生存期 void other(void) static int a = 2; / a, b 为静态局部变量,具有全局寿命,局部可见, static int b; / 只在第一次进入函数时被初始化 int c = 10; / c 为局部变量,具有动态生存期,每次进入函数时都初始化 a += 2; i += 32; c += 5; cout “-OTHER-“ endl; cout “ i: “ i “ a: “ a “ b: “ b “ c: “ c endl; b = a; ,int main() static int a; / a 为静态局部变量,具有全局寿命,局部可见 / b, c 为局部变量,具有动态生存期 int b = -10; int c = 0; cout “-MAIN-“ endl; cout “ i: “ i “ a: “ a “ b: “ b “ c: “ c endl; c += 8; other(); cout “-MAIN-“ endl; cout “ i: “ i “ a: “ a “ b: “ b “ c: “ c endl; i += 10; other(); return 0; ,运行结果: -MAIN- i: 1 a: 0 b: -10 c: 0 -OTHER- i: 33 a: 4 b: 0 c: 15 -MAIN- i: 33 a: 0 b: -10 c: 8 -OTHER- i: 75 a: 6 b: 4 c: 15,例5-2,例5-3,#include using namespace std; class Clock / 时钟类定义 public: / 外部接口 Clock(); void setTime(int NewH, int NewM, int NewS);/ 3个形参均具有函数原型作用域 void showTime(); private: / 私有数据成员 int hour, minute, second; ;,例5-3具有静态和动态生存期对象的时钟程序,/ 时钟类成员函数实现 Clock:Clock() : hour(0), minute(0), second(0) / 默认构造函数 void Clock:setTime(int NewH, int NewM, int NewS) / 3个形参均具有局部作用域 hour = NewH; minute = NewM; second = NewS; void Clock:showTime() cout hour “:“ minute “:“ second endl; ,例5-3,Clock globClock; / 声明全局对象globClock,具有静态生存期,命名空间作用域(文件作用域),由默认构造函数初始化为 0:0:0 int main() / 主函数 cout “The first time output:“ endl; / 引用具有命名空间作用域(文件作用域)的对象globClock;对象的成员函数具有类作用域,显示 0:0:0 globClock.showTime(); globClock.setTime(8, 30, 30); / 将时间设置为 8:30:30 Clock myClock(globClock); / 声明具有块作用域的对象myClock cout “The second time output:“ endl; myClock.showTime(); / 引用具有块作用域的对象myClock return 0; ,运行结果: The first time output: 0:0:0 The second time output: 8:30:30,例5-3,第5章 数据的共享与保护,1、标识符的作用域与可见性 2、对象的生存期 3、类的静态成员(微视频) 4、类的友元 5、共享数据的保护(微视频) 6、多文件结构和编译预处理命令(微视频) 7、综合实例个人银行账户管理程序(微视频) 8、小结,3、类的静态成员,在结构化程序设计中,程序模块的基本单位是函数,因此模块间对内存中数据的共享是通过函数与函数之间的数据共享来实现的,其中包括两个途径参数传递和全局变量。 数据存储在局部对象中,通过参数传递实现共享函数间的参数传递。 数据存储在全局对象中。,使用全局对象,#include int global; void f() global = 5; void g() cout global endl; int main() f(); g(); / 输出“5” return 0; ,将函数与数据封装,#include using namespace std; class Application public: void f();void g(); private: int global; ; void Application:f() global=5; void Application:g() coutglobalendl; ,int main() Application MyApp; MyApp.f(); MyApp.g(); return 0; ,3、类的静态成员,面向对象的程序设计方法兼顾数据的共享与保护,将数据与操作数据的函数封装在一起,构成集成度更高的模块。 类中的数据成员可以被同一类中的任何一个函数访问。这样一方面在类内部的函数之间实现了数据共享,另一方面这种共享是受限制的,可以设置适当的访问控制属性。 把共享只限制在类的范围之内,对类外来说,类的数据成员仍然是隐藏的,达到了共享与隐藏。,3、类的静态成员,在数据共享方面,除了: 函数之间的数据共享参数传递和全局变量 类内部的函数之间实现了数据共享 之外,对象与对象之间也需要共享数据。 静态成员能解决同一个类的不同对象之间数据和函数共享的问题。,3、类的静态成员,例: class Employee private: int empNo; int id; string name; / 字符串对象 ; 如果需要统计雇员总数,这个数据存放在哪里?,3、类的静态成员,例: class Employee Private: int empNo; int id; string name; / 字符串对象 static int count; ; count 这个数据成员是静态数据成员,表示总数。,3、类的静态成员,如果以类外的变量来存储总数,则不能实现数据的隐藏。 如果在类中增加一个数据成员用于存放总数,必然在每一个对象中都存储一个副本。这样不仅使数据冗余,而且每个对象分别维护一个“总数”,容易形成维护对象的成本太高,并且极易造成数据的不一致。 由于这个总数应该是为Employee类的所有对象所共享,因此比较理想的方案是类的所有对象共同拥有一个存放总数的数据成员静态数据成员。,3、类的静态成员,静态数据成员 静态成员函数,静态数据成员,count 这个静态数据成员具有“类属性”,表明这个属性不属于任何一个具体对象,而是为整个类所共有,或者说,为每个对象所共有。 静态成员在每个类只有一个副本,而不是在每一个对象中都存储一个副本。静态成员由该类的所有对象共同维护和使用,从而实现了同一类的不同对象之间的数据共享。 类属性是描述类的所有对象共同特征的一个数据项,对于任何对象实例,它的属性值是相同的。,静态数据成员,静态数据成员 用关键字static声明。 该类的所有对象维护该成员的同一个拷贝。 必须在类外定义和初始化,用作用域运算符(:)来指明所属的类。 静态成员函数 类外代码可以使用类名和作用域运算符(:)来调用静态成员函数。 静态成员函数只能引用属于该类的静态数据成员或静态成员函数。,例5-4 具有静态数据成员的 Point类,class Point / Point类定义 public: / 外部接口 Point(int xx=0, int yy=0) : x(xx), y(yy) / 构造函数 count+; / 在构造函数中对 count 累加,所有对象共同维护同一个 count Point(Point ,int Point:count=0; / 静态数据成员定义和初始化,使用类名限定 int main() / 主函数 Point a(4, 5); / 定义对象a,其构造函数会使 count 增 1 cout “Point A: “ a.getX() “, “ a.getY(); a.showCount(); / 输出对象个数 Point b(a); / 定义对象b,其复制构造函数会使 count 增 1 cout “Point B: “ b.getX() “, “ b.getY(); b.showCount(); / 输出对象个数 cout “Point A: “ a.getX() “, “ a.getY(); a.showCount(); / 输出对象个数 cout “The size of Point: “ sizeof(Point) endl; / 输出8,而不是12 return 0; ,运行结果: Point A: 4, 5 Object count = 1 Point B: 4, 5 Object count = 2 Point A: 4, 5 Object count = 2 The size of Point: 8,例5-4,静态数据成员,在前面的例子中,类Point的数据成员count被声明为静态(static),用来给Point类的对象计数,每定义一个新对象,count的值就相应加1。 静态数据成员count的定义和初始化在类外进行,首先要利用类名来引用(int Point:count=0;),其次,虽然这个静态数据成员是私有类型,在这里却可以直接初始化。除此之外,在类外就不允许直接访问了。 在所有对象声明之前count的值是初始值0。如何输出这个初始值呢?,静态成员函数,类的静态成员函数是专门用来输出静态成员的。 要输出静态成员,可以通过类的某个对象来调用静态成员函数,更可以(更推荐)通过类名来调用静态成员函数。 而非静态成员函数只能通过对象名来调用。 然而,通过静态成员函数访问非静态成员是相当麻烦的。通常,静态成员函数只用来访问同一个类中的静态数据成员,维护对象之间共享的数据。,例5-5 具有静态数据和函数成员的 Point类,class Point / Point类定义 public: / 外部接口 Point(int xx=0, int yy=0) : x(xx), y(yy) / 构造函数 count+; / 在构造函数中对 count 累加,所有对象共同维护同一个 count Point(Point ,int Point:count=0; / 静态数据成员定义和初始化,使用类名限定 int main() / 主函数 Point:showCount(); / 输出对象个数 Point a(4, 5); / 定义对象a,其构造函数会使 count 增 1 cout “Point A: “ a.getX() “, “ a.getY(); Point:showCount(); / 输出对象个数 Point b(a); / 定义对象b,其复制构造函数会使 count 增 1 cout “Point B: “ b.getX() “, “ b.getY(); Point:showCount(); / 输出对象个数 a.showCount(); b.showCount(); return 0; ,运行结果: Object count = 0 Point A: 4, 5 Object count = 1 Point B: 4, 5 Object count = 2 Object count = 2 Object count = 2,例5-5,例5-4与例5-5的比较,采用静态成员函数的好处是可以不依赖于任何对象,直接访问静态数据。,静态成员函数适于访问静态数据成员,静态成员函数可以直接访问该类的静态数据成员和成员函数。而静态成员函数若要访问非静态成员,则必须通过对象名。因此,静态成员函数不适于访问非静态成员。 class A public: static void f(A a); private: int x; ; void A:f(A a) cout x; / 对x的引用是错误的 cout a.x; / 正确 ,第5章 数据的共享与保护,1、标识符的作用域与可见性 2、对象的生存期 3、类的静态成员(微视频) 4、类的友元 5、共享数据的保护(微视频) 6、多文件结构和编译预处理命令(微视频) 7、综合实例个人银行账户管理程序(微视频) 8、小结,4、类的友元,友元是C+提供的一种破坏数据封装和数据隐藏的机制。 通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中本是被隐藏的信息。 可以使用友元函数和友元类。 为了确保数据的完整性,及数据封装与隐藏的原则,建议尽量不使用或少使用友元。,类B的函数能否直接访问类A的私有成员?,class A public: void display() cout x endl; int getX() return x; private: int x; ; class B public: void set(int i) a.x = i; / 错误 void display(); private: A a; ;,如果类B的成员函数是类A的友元函数,则上述set函数中的“a.x=i;”语句就是正确的。,友元关系,友元关系提供了不同类或对象的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。 友元关系就是一个类主动声明哪些其他类或函数是它的朋友,进而给它们提供对本类的访问特许。 通过友元关系,一个普通函数或者类的成员函数可以访问封装于另外一个类中的数据。,友元关系,从一定程度讲,友元是对数据隐蔽和封装的破坏。 但是为了数据共享,提高程序的效率和可读性,在很多情况下,这种小的破坏也是必要的,关键是度的问题。 在一个类中,可以利用关键字friend将其他函数或类声明为友元。如果友元是一般函数或成员函数,称为友元函数;如果友元是一个类,则称为友元类,友元类的所有成员都自动成为友元函数。,4、类的友元,友元函数 友元类,友元函数,友元函数是在类声明中由关键字friend修饰说明的非成员函数,在它的函数体中能够通过对象名访问 private 和 protected成员。 作用:增加灵活性,使程序员可以在封装和快速性方面做合理选择。 访问对象中的成员必须通过对象名。,例5-6 使用友元函数计算两点间的距离,#include #include using namespace std; class Point / Point类定义 public: / 外部接口 Point(int xx=0, int yy=0) x=xx; y=yy; int getX() return x; int getY() return y; friend float dist(Point ,float dist(Point ,运行结果: The distance is: 5,例5-6,使用友元与使用类的组合的比较,对于计算任意两点间距离这个问题来说,使用友元可以使程序具有更好的可读性。 如果是要表示线段,则使用Line类更为恰当。 对于同一个问题,虽然从语法上可以有多个解决方案,但应该根据问题的实质去选择一种能够比较直接地反映问题域本来面目的方案。,友元类,若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员。 声明语法:将友元类名在另一个类中使用friend修饰说明。,友元类举例,class A friend class B; public: void Display() cout x endl; private: int x; class B public: void Set(int i); void Display(); private: A a; ;,void B:Set(int i) a.x = i; void B:Display() a.Display(); ,友元关系是不能传递的,B类是A类的友元,C类是B类的友元,C类与A类之间,如果没有声明,就没有任何友元关系。,友元关系是单向的,如果声明B类是A类的友元,B类的成员函数就可以访问A类的私有和保护数据,但A类的成员函数却不能访问B类的私有、保护数据。,友元关系是不被继承的,如果类B是类A的友元,类B的派生类并不会自动成为类A的友元。这就如同,别人信任你,但是不见得也信任你的孩子。,第5章 数据的共享与保护,1、标识符的作用域与可见性 2、对象的生存期 3、类的静态成员(微视频) 4、类的友元 5、共享数据的保护(微视频) 6、多文件结构和编译预处理命令(微视频) 7、综合实例个人银行账户管理程序(微视频) 8、小结,5、共享数据的保护,虽然数据隐藏保证了数据的安全性,但是各种形式的数据共享却又不同程度地破坏了数据的安全性。 因此,对于既需要共享又需要防止改变的数据,应该将其声明为常量。因为常量在程序运行期间是不可以改变的,所以可以有效地保护数据。,常类型,常类型的对象必须进行初始化,而且不能被更新。 常对象:必须进行初始化,不能被更新。 const 类名 对象名 或:类名 const 对象名 常引用:被引用的对象不能被更新。 const 类型说明符 &引用名 常数组:数组元素不能被更新(后面讲)。 类型说明符 const 数组名大小. 常指针:指向常量的指针(后面讲)。,5、共享数据的保护,常对象 用const修饰的类成员 常引用,常对象,常对象的数据成员值在对象的整个生存期间不能被改变。即:常对象必须进行初始化,而且不能被更新。 声明常对象的语法形式: const 类型说明符 对象名; 或: 类型说明符 const 对象名; 与基本数据类型的常量相似,常对象的值也是不能被改变的。,常对象举例,class A public: A(int i,int j) x=i; y=j; . private: int x,y; ; const A a(3, 4); / a是常对象,不能被更新,常对象,C+语法如何保障类型的常对象的值(常对象的数据成员)不被改变呢? 改变对象的数据成员值可以通过类的成员函数进行。因此,语法规定不能通过常对象来调用普通的成员函数。 可是如此一来,常对象还有什么用呢?因为这样的话,常对象就没有任何可用的对外接口了。 常成员函数可以解决这个问题。,用const修饰的类成员,常成员函数 使用const关键字说明的函数。 常成员函数不更新对象的数据成员。 常成员函数说明格式: 类型说明符 函数名(参数表)const; 这里,const是函数类型的一个组成部分,因此在实现部分也要带const关键字。 const关键字可以被用于参与对重载函数的区分 通过常对象只能调用它的常成员函数。 常数据成员 使用const说明的数据成员。,例5-7 常成员函数举例,#include using namespace std; class R public: R(int r1, int r2) R1=r1; R2=r2; void print(); void print() const; private: int R1, R2; ;,void R:print() cout R1 “:“ R2 endl; void R:print() const cout R1 “;“ R2 endl; int main() R a(5, 4); a.print(); / 调用void print() const R b(20, 52); b.print(); / 调用void print() const return 0; ,运行结果: 5:4 20;52,例5-7,函数重载的3种情况,C+允许功能相近的函数在相同的作用域内以相同的函数名定义,从而形成函数重载。函数重载必须在满足下列3种情况之一时才能成立:,例5-8 常数据成员举例,#include using namespace std; class A public: A(int i); void print(); private: const int a; / 常数据成员 static const int b; / 静态常数据成员 ;,const int A:b=10; / 静态常数据成员在类外说明和初始化 A:A(int i):a(i) / a(i)常数据成员只能通过初始化列表来获得初值 void A:print() cout a “:“ b endl; int main() / 建立对象a1和a2,并以100和0作为初值,分别调用构造函数, / 通过构造函数的初始化列表给对象的常数据成员赋初值 A a1(100), a2(0); a1.print(); a2.print(); return 0; ,运行结果: 100:10 0:10,例5-8,常引用,如果在声明引用时用const修饰,被声明的引用就是常引用。 常引用所引用的对象不能被更新。 如果用常引用作形参,就不会意外地发生对实参的更改。 常引用的声明形式如下: const 类型说明符 ,例5-9 常引用作形参,#include #include using namespace std; class Point / Point类定义 public: / 外部接口 Point(int xx=0, int yy=0) : x(xx), y(yy) int getX() return x; int getY() return y; friend float dist(const Point ,float dist(const Point ,例5-9,运行结果: The distance is: 5,第5章 数据的共享与保护,1、标识符的作用域与可见性 2、对象的生存期 3、类的静态成员(微视频) 4、类的友元 5、共享数据的保护(微视频) 6、多文件结构和编译预处理命令(微视频) 7、综合实例个人银行账户管理程序(微视频) 8、小结,6、多文件结构和编译预处理命令,C+程序的一般组织结构 外部变量与外部函数 标准C+库 编译预处理,C+程序的一般组织结构,一个源程序可以划分为多个源文件: 类声明文件(.h文件) 类实现文件(.cpp文件) 类的使用文件(main()所在的.cpp文件) 利用工程(project)来组合各个文件。,例5-10 文件1,类的声明,point.h,/ 文件1,类的声明,point.h #ifndef POINT_H #define POINT_H class Point / 类的定义 public: / 外部接口 Point(int xx=0, int yy=0) : x(xx), y(yy) count+; Point(const Point #endif,例5-10 文件2,类的实现,Point.cpp,/ 文件2,类的实现,Point.cpp #include “Point.h“ #include using namespace std; int Point:count=0; / 使用类名初始化静态数据成员 Point:Point(const Point ,例5-10 文件3,主函数,5_10.cpp,#include “Point.h“ #include using namespace std; int main() Point a(4,5); / 定义对象 a,其构造函数会使 count 增 1 cout “Point A: “ a.getX() “, “ a.getY(); Point:showCount(); / 输出对象个数 Point b(a); / 定义对象 b,其构造函数会使 count 增 1 cout “Point B: “ b.getX() “, “ b.getY(); Point:showCount(); / 输出对象个数 return 0; ,运行结果: Point A: 4, 5 Object count=1 Point B: 4, 5 Object count=2,外部变量与外部函数,为了使变量除了在定义它的源文件中可以使用外,还要被其他文件使用,可以将其声明为外部变量,用extern关键字来说明。 如果在声明一个函数原型时或定义函数时冠以static关键字来修饰,就将函数的作用域限制在了当前的编译单元内,这时编译器要求当前编译单元内必须包含函数的定义,而且此函数定义只在当前编译单元内可见。这样在其他的编译单元中,就不能调用这个函数。,外部变量.cpp,#include using namespace std; int i = 3; / 全局变量,文件作用域 void next(void); int main() i+; next(); cout “i=“ i endl; / 输出 5 return 0; void next() i+; ,运行结果: i=5,/ 文件名:外部变量1.cpp #include using namespace std; int i = 3; / 全局变量,文件作用域 void next(); int main() i+; next(); cout “i=“ i endl; return 0; ,/ 文件名:外部变量2.cpp extern int i; / static void next(void); void next(void) / 外部函数 i+; ,运行结果: i=5,外部变量.cpp,若“外部变量2.cpp”写成如下形式: extern int i; static void next(void); void next(void) / 外部函数 i+; 则该文件的编译可以通过,但是在连接时出错。,标准C+库,标准C+类与组件在逻辑上分为6种类型: 输入输出类; 容器类与ADT(抽象数据模型) 存储管理类; 算法; 错误处理; 运行环境支持。 对库中预定义内容的声明分别存在于不同的头文件中,要使用这些预定义的成分,就要将相应的头文件包含到源程序中(使用#include预处理指令)。,标准C+库,使用标准C+库时,还需要加入下面这一条语句来将指定命名空间中的名称引入到当前作用域中: using nam

    注意事项

    本文(第5章数据的共享与保护.ppt)为本站会员(本田雅阁)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    经营许可证编号:宁ICP备18001539号-1

    三一文库
    收起
    展开