创建静态成员和友元的目的:
创建静态成员主要是解决数据共享问题,而创建友元的目的是为了让某些函数访问类中的私有成员。
1…静态数据成员
思考:为什么要定义静态数据成员?
答:如果不定义为静态数据成员,那么每个对象都分别有一个i的副本(拷贝)。但定义为静态数据成员之后,所有的对象共享有一个i的副本,就是说i在内存里就一个副本。
那么,不同对象引用i,对i改变的话, 其他对象中i的值也会被改变,而且所有对象的值都是相同的。
在引用静态数据成员时,可以不通过对象而通过类,静态数据成员在内存只有一个,而且可以通过类来引用。这是静态数据成员属于类,很明显的。
这是实现不同对象间数据共享的一种方法。
(1)静态数据成员在定义或说明时前面加关键字 static 。
例: …….
Private:
Int a,b,c;
Static int s
;
(2) 静态数据成员一般在类定义外部按特定的格式进行初始化。(静态数据成员是在程序开始运行时被分配空间的,到程序结束时才释放空间,所以可以在建立对象前就可以为静态数据成员赋值)
其格式为:
< 数据类型 >< 类名 >::< 静态数据成员名 >=< 值 >;
例:
class Nclass
{
……..
private:
static int a;
…….
};
int Nclass::a=5;
引用静态数据成员时,采用如下格式:
< 类名 >::< 静态成员名 >
(3)实例
class Sample
{
int n;
static int sum;
public:
Sample(int x) { n = x; }
void add() { sum += n; }
void disp()
{
cout << "n=" << n << ",sum=" << sum << endl;
}
};
int Sample::sum = 0; // 静态数据成员赋初值
void main()
{
Sample a(2), b(3), c(5);
a.add();
a.disp();
b.add();
b.disp();
c.add();
c.disp();
}
执行结果:
n=2,sum=2
n=3,sum=5
n=5,sum=10
可以看出
静态数据成员有以下特点:
1.对于非静态数据成员,每个类对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷 贝,由该类型的所有对象共享访问。(也就是说,静态数据成员是该类的所有对象所共有的。)对该类的多个对象来说,静态数据成员只分配一次内存,供所有对象共 用。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新;
2.静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。在该例子中,语句int Sample ::Sum=0;是定义静态数据成员;
3. 静态数据成员和普通数据成员一样遵从public,protected,private访问规则;
4.因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它;
2…静态成员函数:
(1)思考:为什么要定义静态成员函数?
答:一般这些函数都是用来对这个类进行操作的。例如,你要修改一个静态成员数据,那么需要静态成员函数。
(2) 调用格式为: classname::static Func()
(3)重点:静态成员函数不属于任何对象,它属于类,所以静态成员函数中没有this指针,所以在静态成员函数中,无法访问本类的非静态数据成员。
静态成员函数既可以在类中定义,也可以在类外定义;静态成员函数在类外定义时,不需要用static前缀;
3…类的友元:
把friend double Distance()放入point类中,为友元函数。
class A
{
private:
int _i;
friend class B;
};
class B
{
public:
void fn();
};
B类是A类的友元类,则B类的所有成员函数都是A类的友元函数,B中的任何元素都可以访问A类的私有和保护成员(注意是单向的)。
class Point
{
private:
int _x;
int _y;
//public:
static int _count;
public:
Point(int x=0, int y=0)
:_x(x), _y(y)
{
_count++;
}
~Point()
{
_count--;
}
static int GetCount(/*Point* pthis*/)
//没有this指针,
//在静态成员函数中,
//无法对本类的非静态成员进行默认访问
{
//Point p;
//p.SetX(10);
//pthis->_x = 90;
return _count;
}
//int GetX() { return _x; }
//int GetY() { return _y; }
void SetX(int x)//有this指针
{
_x = x;
}
friend double Distance(const Point& p1, const Point& p2);
};
int Point::_count = 0;
double Distance(const Point& p1, const Point& p2)
{
return pow(pow((p1._x - p2._x), 2) + pow((p1._y - p2._y), 2), 0.5);
}
int main4()
{
// cout << Point::_count << endl;
Point p1(7, 1), p2(9, 7);
cout << Distance(p1, p2) << endl;
return 0;
}