C入门第五章 数据的共享与保护PPT课件
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
c=c+8;
other( );
cout<<"---MAIN---\n";
cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
i=i+10;
other( ); }
-24-
2020/12/1
void other(void)
{
static int a=2; // a, b为静态局部变量,具有全局寿命,局部可见。
❖ 该变量将一直存在,不会随函数调用返回而消失,静态变 量的值会一直保持
❖ 多次调用函数时,静态变量不会创建多个副本
-21-
2020/12/1
动态生存期
除全局变量、静态局部变量外的所有变量均为动态 生存期的变量
特点:从声明点之处起,结束于命名该标识符的作 用域结束。
-22-
2020/12/1
例
第五章 —数据的共享与保护
-1-
2020/12/1
本章主要内容
作用域与可见性 对象的生存期 类的静态成员 友元 共享数据的保护 多文件结构与编译预处理命令
-2-
2020/12/1
作用域
Share_Protect.cpp(12) : error C2065: ‘a' : undeclared identifier
//内层访问 //输出全局i :6 全局据变量
的方法
2020/12/1
对象的生存期
生存期:对象从产生——〉销毁,即为它的生存期。 在对象生存期内,对象将保持它的值,直到被更新为
止。
代码区
代码区全局数据区
堆区 栈区
全局变量、常量、静态变量 (全局、局部)
动态分配的内存 局部变量等
默认初 值为0
运行时,程序装载到内存后的分布
using namespace std;
class Clock
//时钟类声明
{public:
//外部接口
Clock();
void SetTime(int NewH, int NewM, int NewS); //三个形参均具有函数原型作用域
void ShowTime();
~Clock(){}
private:
所在的块结束的大括号止
局部变量:具有局部作用域的变量
-6-
2020/12/1
局部作用域
在块中声明的标识符,其作用域自声明处起, 限于本块中,例如:
void fun(int a)
{ int b(a);
cin>>b;
if (b>0)
{
int c;
......
c的作用域
}
a的作用域 b的作用域
…… }
-26-
2020/12/118
思考:
❖ 如何统计一个函数被调用的次数? ❖ 如:SimpleCAI中如何统计做了多少次的练习? ❖ 修改SimpleCAI,控制练习次数,如已经达到3次,则告
知“ 练习结束,请注意休息!”
-27-
2020/12/1
例5-3具有静态、动态生存期对象的时钟程序
#include<iostream>
-7-
2020/12/1
特别说明:VC6中,循环变量从定义之处 起,在本函数内均有效
标准c++中:
for( int i;i<10;i++) { …… } ……
vc 6.0中:
i的作用域
for( int i;i<10;i++) { …… } ……
i的作用域
-8-
2020/12/1
类作用域
类作用域:类定义内部和其所有成员函数的定义 体。
i ++;
cout<<"i="<<i<<",a="<<a<<endl;
}
-23-
2020/12/1
例5-2 变量的生存期与可见性
#include<iostream>
using namespace std;
int i=1;
// i 为全局变量,具有静态生存期。
int main( ) {
static int a;
-20-
2020/12/1
静态生存期
静态生存期:与程序的运行期相同。
❖ 具有命名空间作用域的变量(全局变量)
❖ 在函数内部声明的静态局部变量
静态局部变量:
注意与普通 变量的区别
❖ 定义:在局部变量前加上 static,即为静态局部变量
❖ 存储位置:存放在全局数据区,默认初值为0
❖ 特点:
❖ 函数第一次调用时,建立静态变量
cout << x << endl;
cout << y << endl;
cout << second::x << endl;
cout << second::y << endl;
return 0;
}
-13-
2020/12/1
命名空间也可嵌套 特殊的命名空间:
❖ 全局命名空间(默认、缺省)
❖前面所写的程序中,所有的函数等均属于全局命名空间 ❖若在任意函数的外面声明的变量,则该变量属于全局命名 空间,具有全局命名空间作用域====》全局变量
WHY?
-3-
2020/12/1
作用域
作用域:
❖ 标识符的有效范围
C++的几种常见作用域
❖ 函数原型作用域 ❖ 局部作用域 ❖ 类作用域 ❖ 名字空间作用域(全局作用域)
-4-
2020/12/1
函数原型的作用域
函数原型中的参数,其作用域始于 "(",结束于")"。 例如,设有下列原型声明:
❖ 匿名命名空间
❖用于隐藏不想暴露给别的文1
#include <iostream>
using namespace std;
int i;
//在全局命名空间中的全局变量
namespace Ns {
int j;
//在Ns命名空间中的全局变量
}
int main() {
Ns::j = 6;
可直接引用 int y = 10; }
namespace second{
double x = 3.1416;
double y = 2.7183;
}
int main () {
uussininggfifrisrts:t::x:;x;
uussininggsesceocnodn:d:y::;y;
cout << x << endl;
return 0;
}
-15-
2020/12/1
关于全局数据的结论:
❖ 全局数据包括:全局变量、全局常量、全局对象(在命 名空间中定义的对象)
❖ 当大多数函数都要访问某个数据时,可以将之定义为全 局变量,免于参数传递
❖ 缺点:破坏了模块的独立性 ❖ 全局数据在定义时时如没有初始化,则自动置为0(全局
b=a;
}
-25-
2020/12/1 17
运行结果: ---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
double volume(double radius);
double Area ( double radius );
radius 的作用域仅在于此,不 能用于程序正文其它地方,因 而可有可无。
-5-
2020/12/1
局部作用域
在函数中声明的变量(对象),具有局部作用域
❖ 函数形参:从声明之处起,至函数体结束止,有效 ❖ 函数体内声明的对象(变量),从声明之处起,至声明
static int b;
//只第一次进入函数时被初始化,默认值为0。
int c=10; // C为局部变量,具有动态生存期,每次进入函数时都初始化
a=a+2;
i=i+32;
c=c+5;
cout<<"---OTHER---\n";
cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
类的成员函数M具有类作用域,对M的访问方式 如下:
❖ 如果在类的任意成员函数中,没有声明与M同名的局 部作用域标识符,那么在该函数内可以直接访问成员
M。
❖ 类外的函数、类
❖ x.M
//通过对象x访问M(仅当M是public)
❖ X::M
//通过类名访问M(仅当M是静态成员)
❖ 通过表达式prt->M
//局部变量
i = 7; cout << “Local i = ” << i<<endl;
cout<< “Global i = ” <<:: i << endl;
局部变量i 的//输作出7用域
//输出5
::i++;
}
cout << “i = ” << i << endl;
return 0;
}
-19-
❖ 作用int:x将= 5指; 定命名空间的所有标识符暴露在当前作用域中
int y = 10;
}
namespace second {
double x = 3.1416;
double y = 2.7183;
}
int main () {
using namespace first; //将first 空间的标识符全部暴露,可直接引用
//私有数据成员
int Hour,Minute,Second;
};
-28-
2020/12/1
//时钟类成员函数实现
Clock::Clock() //构造函数 { Hour=0;
Minute=0; Second=0; } void Clock::SetTime(int NewH, int NewM, int NewS{ Hour=NewH; Minute=NewM; Second=NewS; } void Clock::ShowTime(){ cout<<Hour<<":"<<Minute<<":"<<Second<<endl; }
即:内层同名变量会屏蔽掉外层同名变量
命名空间作用域
类作用域
块作用域
-18-
2020/12/1
#include <iostream>
using namespace std;
int i;
//在全局命名空间中的全局变量
int main() {
i = 5;
//为全局变量 i 赋值
{
//子块1
int i;
// 静态局部变量,有全局寿命,局部可见。
int b=-10;
// b, c为局部变量,具有动态生存期。
int c=0;
void other(void);
//函数声明
cout<<"---MAIN---\n";
cout<<" i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
cout << y << endl;
cout << first::y << endl;
cout << second::x << endl;
return 0;
-12-
2020/12/1
#法inc三lude <iostream>
using namespace std; na❖meusspinagce nfairmstes{pace 命名空间名;
对象则自动调用默认构造函数初始化)
-16-
2020/12/1
可见性
可见性:决定了标识符是否能被引用
❖即使有效,但可能不能被引用
如果标识在某处可见,则就可以在该处引用此标识 符。
-17-
2020/12/1
可见性原则:
无包含关系的两作用域中声明的同名标识符, 互不影响。
相互包含的两个作用域,若内、外层中声明了 同名标识符,则外层标识符在内层不可见。
//通过指针(见第6章)
-9-
2020/12/1
命名空间作用域
命名空间:用于解决名字(标识符)的同名冲突 命名空间的定义:
❖namespace name { 函数声明; 变量声明; 类声明;………… };
命名空间作用域:
❖在命名空间中,凡是不属于该命名空间下函数原型、函数体、类中声 明的标识符,均属于命名空间作用域 ❖命名空间作用域的标识符,在本命名空间中任何地方均可使用
#include<iostream>
using namespace std; void fun();
运行结果:
int main() {
fun();
i=6, a=2 i=6, a=3
fun(); }
i是动态生存期
void fun() {
a是静态生存期
static int a=1;
int i = 5;
a ++;
//为全局变量 j 赋值
int x=10;
//局部变量
cout << "i = " << i << endl;
//输出0
cout << "j = " << NS::j << endl;
//输出6
cout << “x = " <<x<< endl;
//输出10
i = 5;
cout << "i = " << i << endl;
-10-
2020/12/1
不同命名空间中标识符的引用(法一)
❖ 命名空间名::标识符名
-11-
2020/12/1
法二: #include <iostream>
using namespace std; ❖ using 命na名m空es间pa名ce:f:i标rst识{符名