5.1 标识符的作用域与可见性
作用域是一个标识符在程序正文中有效的区域。
分类:函数原型作用域,局部作用域(块作用域),类作用域和命名空间作用域。
标识符的有效范围即标识符的可见性。
程序运行到某一点,能够引用到的标识符,就是该处可见的标识符。
5.2 对象的生存期
分为静态生存期和动态生存期两种。
5.2.1 静态生存期
静态生存期与程序的运行期相同。在文件作用域中声明的对象具有这种生存期。在函数内部声明静态生存期对象,要冠以关键字static。
5.2.2动态生存期
开始于程序执行到声明点时,结束于命名该标识符的作用域结束处。块作用域中声明的,没有用static修饰的对象是动态生存期的对象。局部生存期对象。
5.3 类的静态成员
解决同一个类不同对象之间数据和函数共享问题的。例如,可以抽象某公司的全体雇员的共性,设计如下雇员类:
class Employee {
private:
int No;
int id;
string name;
.......
}
如果需要统计雇员总数,这个数据存放在什么地方呢?若以类外的变量来存储总数,不能实现数据隐藏。若在类中增加一个数据成员存放总数,必然在每一个对象都存储一个副本,不仅多余而且每个对象分别维护一个总数,容易造成数据不一致性。由于这个数据应该是为Emploee类所有对象共享的,比较理想的方案是类的所有对象共同拥有一个用于存放总数的数据成员。
5.3.1 静态数据成员
实例属性在C++程序中以类的非静态数据成员表示。比如:Employee类中的No,id,name
如果某个属性为整个类所共有,不属于任何一个具体对象,则采用static关键字来声明静态成员。静态成员在每一个类中只有一个副本,由该类的所有对象共同维护和使用,对任何实例它的属性值是相同的。静态数据成员具有静态生存期。用法是”类名::标识符“。在类定义之外再加以定义设计因为需要以这种方式专门为它们分配空间。
例 具有静态数据成员的Point类
class Point{
public:
Point(int x=0,int y=0):x(x), y(y){ //构造函数 对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;
}
运行结果:
Point A:4,5 object count=1
Point B:4,5 object count=2
5.3.2 静态函数成员
使用static关键字声明函数成员。同静态数据成员一样,属于整个类,由同一个类的所有对象共同拥有,为这些对象所共享。静态成员函数可以直接访问该类的静态数据和函数成员。而访问非静态成员,必须通过对象名。
例:具有静态函数成员的Point类
class Point{
public:
Point(int x=0,int y=0):x(x), y(y){ //构造函数 对count累加
count++;
}
Point(Point &p) //复制构造函数
{
x = p.x;
y = p.y;
count++;
}
~Point() {
count--; //析构函数
}
int getX(){
return x;
}
int getY(){
return y;
}
static 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();
Point::showCount(); // 输出对象个数
Point b(a);
cout<<"Point B:"<<b.getX()<<","<<b.getY();
b.showCount(); // 输出对象个数
return 0;
}
5.4 类的友元
友元关系提供不同类或对象的成员函数之间、类的成员函数与一般函数之间进行数据共享的机制。
用关键字friend将其他函数或类声明为友元。
建议慎用友元,破坏封装数据隐藏。