C++第五章 : 数据的共享与保护
/*
5.1 标识符的作用域与可见性
定义:作用域是一个标识符在程序正文中有效的区域,分为函数原型作用域、局部作用域、类作用域和命名空间作用域
1、函数原型作用域(最小)
例如 double area(double radius);
标识符radius的作用范围就是函数area形参列表的左右括号之间
2、局部作用域
void fun (int a)
{
a的作用域{}之间所有的部分
int b=a;
cin>>b;
b的作用域int b=a;到cin>>b;这两句语句中
}
3、类作用域
类可以被看做是一组有名成员的集合,类X的成员m具有类作用域,对m的访问
(1)如果在X的成员函数中没有声明同名的局部作用域标识符,那么在该函数内可以直接访问。
(2)通过表达式x.m或者X::m.这正是程序中访问对象成员的最基本方法
(3)通过ptr->m这样的表达式,其中ptr为指向X类的一个对象的指针。
4、命名空间作用域
using namespace 命名空间名
如果没有上面这句话,则需要引用该空间内的标识符时,前面必须添加空间名
如std::cin等
5.2 对象的生存期
生存期:从诞生到结束的这段时间就是它的生存期
1、静态生存期
如果对象的生存期与程序的运行期相同,则称它具有静态生存期。
在命名空间作用域中声明的帝乡都是具有静态生存期的。如果要在函数内部的局部
作用域中声明具有静态生存期的对象,则要使用关键字 static
例如:
static int i=5;
这表示i会被赋予5初始化,而非每次执行函数时都将i赋值为5
如未指定初值,则默认为0;
2、动态生存期
在局部作用域中声明的具有动态生存期的对象,习惯上也称为局部生存期对象,其诞生于声明点,结束于所在模块执行完毕之时。
//5_2.cpp
#include
using namespace std;
int i=1;//i为全局变量具有静态周期
void other()
{
//a,b为静态局部变量,具有其全局寿命,局部可见,只第一次进入函数时会被初始化
static int a=2;
static int b;
//c为局部变量,具有动态生存周期,每次进入函数时都要初始化
int c=10;
a+=2;
i+=32;
c+=5;
cout<<“other”<<endl;
cout<<“i:”<<i<<“a:”<<a<<“b:”<<b<<“c:”<<c<<endl;
b=a;
}
int main()
{
//a为静态全局变量,具有全局寿命,局部可见
static int a;
//b,c为局部变量,具有动态生存周期
int b=-10;
int c=0;
cout<<“main”<<endl;
cout<<“i:”<<i<<“a:”<<a<<“b:”<<b<<“c:”<<c<<endl;
i+=10;
other();
return 0;
}
5.3、类的静态成员
在结构化程序设计中,程序模块的基本单位是函数,因此模块间对内存中数据的共享
是通过函数与函数之间的数据共享来实现的,其中包括两个途径—参数传递和全局
变量。
静态成员是解决同一个类的不同对象之间数据核函数共享问题的。例如,可以抽象出某公司
全体员工的共性,设计如下员工类:
class Employee
{
private:
int empNo;
int id;
string name;
}
1、静态数据成员
面向对象方法中还有类属性的概念。如果某个属性为整个类所共有,不属于任何一个具体对象,
则采用static关键字来声明为静态成员。静态成员在每个类只有一个副本,由该类的所有对象共同维护和使用
从而实现了同一类的不同对象之间的数据共享。
//5_4.cpp具有静态数据成员的Point类
#include
using namespace std;
class Point
{
public:
Point (int x=0,int y=0):x(x),y(y){
//在构造函数中对count累加,所有对象共同维护同一个count
count++
}
Point(Point &p)
{
x=p.x;
y=p.y;
count++;
}
~Point(){count --;}
int getX(){return x;}
int getY(){return y;}
void showCount()
{
cout<<“Object count”<<count <<endl;
}
private:
int x,y;
static int count;//静态数据成员声明,用于记录点的个数
};
int Point::count=0;//静态数据成员定义和初始化,使用类名限定
int main()
{
Point a{4,5};
cout<<“Point A:”<<a.getX()<<","<<a.getY();
a.showCount();
Point b(a);
cout<<“Point B:”<<b.getX()<<","<<b.getY();
b.showCount();
return 0;
}
2、静态函数成员
静态成员函数可以只及访问该类的静态数据和函数成员。而访问非静态成员,必须通过对象名。
class A{
public:
static void f(A a);
private:
int x;
};
void A::f(A a)
{
cout<<x;//对x的引用时错误的
cout<<a.x;//正确
}
5.4、类的友元
友元函数是在类中用关键字friend修饰的非成员函数。
友元函数可以是一个普通的函数,也可以是其他类的成员函数。虽然它不是本类的成员函数,
但是在它的函数体中可以通过对象名访问类的私有和保护成员。
在UML语言中,友元函数是通过在成员函数前方加《friend》构造型来表征
例如:
friend float dist(Point &p1,Point &p2);//友元函数声明
float dist(Point &p1,Point &p2)//友元函数实现
{
}
5.5、共享数据的保护
*/
/*
//5_2.cpp
#include
using namespace std;
int i = 1;//i为全局变量具有静态周期
void other()
{
//a,b为静态局部变量,具有其全局寿命,局部可见,只第一次进入函数时会被初始化
static int a = 2;
static int b;
//c为局部变量,具有动态生存周期,每次进入函数时都要初始化
int c = 10;
a += 2;
i += 32;
c += 5;
cout << "other" << endl;
cout << "i=" << i << "\ta=" << a << "\tb=" << b << "\tc=" << c << endl;
b = a;
}
int main()
{
//a为静态全局变量,具有全局寿命,局部可见
static int a;
//b,c为局部变量,具有动态生存周期
int b = -10;
int c = 0;
cout << "main" << endl;
cout << "i=" << i << "\ta=" << a << "\tb=" << b << "\tc=" << c << endl;
i += 10;
other();
return 0;
}
*/
/*
//5_4.cpp具有静态数据成员的Point类
#include
using namespace std;
class Point
{
public:
Point(int x = 0, int y = 0) :x(x), y(y) {
//在构造函数中对count累加,所有对象共同维护同一个count
count++;
}
Point(Point &p)
{
x = p.x;
y = p.y;
count++;
}
~Point() { count–; }
int getX() { return x; }
int getY() { return y; }
void showCount()
{
cout << “Object count” << count << endl;
}
private:
int x, y;
static int count;//静态数据成员声明,用于记录点的个数
};
int Point::count = 0;//静态数据成员定义和初始化,使用类名限定
int main()
{
Point a{ 4,5 };
cout << “Point A:” << a.getX() << “,” << a.getY();
a.showCount();
Point b(a);
cout << “Point B:” << b.getX() << “,” << b.getY();
b.showCount();
return 0;
}
*/