面向对象中的static

  之前写了一篇面向过程的static,现在来认识一下面向过程的static。面向过程的static主要体现在三个方面。修饰全局变量,修饰局部变量和修饰函数。在面向对象中,主要体现在以下两方面:

修饰成员变量

用法:声明时在成员变量类型前加static。初始化时要在类外进行。

class A
{
    private:
        static int a;//声明静态成员变量a;
};

int A::a=0;//初始化静态成员变量a;

改变: 存储位置发生改变,他的数据会保存在数据段中(有一些文章会写存入全局数据区,静态数据区的,首先全局数据区就是静态数据区,他们都位于数据段)。这将发生一系列连锁的变化。

  1. 在定义时就要为静态成员变量分配内存空间,类只有在实例化时才会分配空间,所以不能在类内定义。

  2. 对于非静态成员变量,每个类对象都有自己的拷贝,分配不同的内存空间。而静态成员变量被当作是类的成员。无论这个类的对象被定义了多少个,静态成员变量在程序中也只有一份,只占据一块内存空间,由该类型的所有对象共享访问。所以静态成员变量在每个对象中都是一样的。

  3. 因为静态成员变量在数据段分配内存,属于本类的所有对象共享,所以,它不属于特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它。
    如果静态成员变量的访问权限允许的话(即public的成员),可在程序中引用静态成员变量:
    <类对象名>.<静态成员变量名> 或 <类类型名>::<静态成员变量名>

未变: 静态数据成员和普通数据成员一样遵从public,protected,private访问规则;

作用: 一个类声明的对象中,静态成员变量是可以当全局变量使的。或在继承中,如果在基类中声明一个静态成员变量。那么,在基类和子类所声明的对象中,这个静态成员变量可以有和全局变量有一样的功效。而且还比全局变量有优势。
静态成员变量相较全局变量的优势:
1. 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性。
2. 可以封装,实现信息隐藏。静态数据成员可以是private成员,而全局变量不能。

修饰成员函数

用法:声明时在返回值类型前加static,定义时不能加。调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
<类名>::<静态成员函数名>(<参数表>)

class A
{
    public:
        static void function();//声明静态成员函数
};
//定义静态成员函数
void A::function()
{
    ……
}
//调用静态成员函数
A a;
a.function();
A::function();

改变:在类的内部实现,也就是说该类的全部服务而不是为某一个类的具体对象服务。正因如此它也没有this指针。
  普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是缺省的。如函数fn()实际上是this->fn()。
  由于没有this指针它无法访问属于类对象的非静态成员变量,也无法访问非静态成员函数,它只能调用其余的静态成员函数。

未变:还是可以被非静态成员函数任意地访问。

作用:由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长。

#include<iostream>

using namespace std;

class A
{
    public:
        A(int x,int y):a(x),b(y){}
        int GetSum();
        static void PrintSum();
    private:
        int a,b;
        static int sum;
};

int A::sum=0;

int A::GetSum()
{
    return sum=a+b;
}

void A::PrintSum()
{
    cout<<sum<<endl;
}

int main()
{
    A a1(1,2);
    A a2(2,3);
    cout<<a1.GetSum()<<endl;
    cout<<a2.GetSum()<<endl;
    a1.PrintSum();
    A::PrintSum();

    return 0;
}

输出结果:

3
5
5
5

总结

  其实static关键字给所修饰对象带来的最大改变就是存储位置的改变,所以内存区段的划分对我们理解编程还是有着很重要的意义的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值