c++ static

转载自:http://blog.csdn.net/majianfei1023/article/details/45290467#

C++ 语言的 static 关键字有二种用途:
当然以上的几种,也可以用在c++中。还有额外的两种用法:

1.静态数据成员:用于修饰 class 的数据成员,即所谓“静态成员”。这种数据成员的生存期大于 class 的对象(实体 instance)。静态数据成员是每个 class 有一份,普通数据成员是每个 instance 有一份,因此静态数据成员也叫做类变量,而普通数据成员也叫做实例变量。

#include<iostream>


using namespace std;


class Rectangle
{
private:
    int m_w,m_h;
    static int s_sum;

public:
    Rectangle(int w,int h)
    {
        this->m_w = w;
        this->m_h = h;
        s_sum += (this->m_w * this->m_h);
    }


    void GetSum()
    {
        cout<<"sum = "<<s_sum<<endl;
    }


};


int Rectangle::s_sum = 0;  //初始化




int main()
{
    cout<<"sizeof(Rectangle)="<<sizeof(Rectangle)<<endl;
    Rectangle *rect1 = new Rectangle(3,4);
    rect1->GetSum();
    cout<<"sizeof(rect1)="<<sizeof(*rect1)<<endl;
    Rectangle rect2(2,3);
    rect2.GetSum();
    cout<<"sizeof(rect2)="<<sizeof(rect2)<<endl;

    system("pause");
    return 0;
}

sizeof(Rectangle)=8bytes=sizeof(m_w)+sizeof(m_h)。也就是说 static 并不占用Rectangle的内存空间。
那么static在哪里分配内存的呢?是的,全局数据区(静态区)。
再看看GetSum(),第一次12=3*4,第二次18=12+2*3。由此可得,static只会被初始化一次,于实例无关。

结论:

对于非静态数据成员,每个类对象(实例)都有自己的拷贝。而静态数据成员被当作是类的成员,由该类型的所有对象共享访问,对该类的多个对象来说,静态数据成员只分配一次内存。
静态数据成员存储在全局数据区。静态数据成员定义时要分配空间,所以不能在类声明中定义。

也就是说,你每new一个Rectangle,并不会为static int s_sum的构建一份内存拷贝,它是不管你new了多少Rectangle的实例,因为它只与类Rectangle挂钩,而跟你每一个Rectangle的对象没关系。

2、静态成员函数:用于修饰 class 的成员函数。
我们对上面的例子稍加改动:

#include<iostream>


using namespace std;


class Rectangle
{
private:
    int m_w,m_h;
    static int s_sum;

public:
    Rectangle(int w,int h)
    {
        this->m_w = w;
        this->m_h = h;
        s_sum += (this->m_w * this->m_h);
    }


    static void GetSum()  //这里加上static
    {
        cout<<"sum = "<<s_sum<<endl;
    }


};


int Rectangle::s_sum = 0;  //初始化




int main()
{
    cout<<"sizeof(Rectangle)="<<sizeof(Rectangle)<<endl;
    Rectangle *rect1 = new Rectangle(3,4);
    rect1->GetSum();
    cout<<"sizeof(rect1)="<<sizeof(*rect1)<<endl;
    Rectangle rect2(2,3);
    rect2.GetSum();  //可以用对象名.函数名访问
    cout<<"sizeof(rect2)="<<sizeof(rect2)<<endl;
    Rectangle::GetSum();  //也可以可以用类名::函数名访问


    system("pause");
    return 0;
}

上面注释可见:对GetSum()加上static,使它变成一个静态成员函数,可以用类名::函数名进行访问。
那么静态成员函数有特点呢?
1.静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
2.非静态成员函数可以任意地访问静态成员函数和静态数据成员;
3.静态成员函数不能访问非静态成员函数和非静态数据成员;
4.调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以用类名::函数名调用(因为他本来就是属于类的,用类名调用很正常)

前三点其实是一点:静态成员函数不能访问非静态(包括成员函数和数据成员),但是非静态可以访问静态,有点晕吗?没关系,我给你个解释,
因为静态是属于类的,它是不知道你创建了10个还是100个对象,所以它对你对象的函数或者数据是一无所知的,所以它没办法调用,而反过来,你创建的对象是对类一清二楚的(不然你怎么从它那里实例化呢),所以你是可以调用类函数和类成员的,就像不管GetSum是不是static,都可以调用static的s_sum一样。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值