static的使用

静态变量基本认知

使用static定义的变量称为静态变量,可细分为静态全局变量、静态局部变量、静态函数。

静态全局变量和普通全局变量的区别

作用域不同:全局变量的作用域是整个工程,也就是在整个工程的不同文件夹中可以共享全局变量

       静态全局变量的作用域是包含它的当前源文件

静态全局变量和普通全局变量都存放在全局数据区,如果没有初始化,系统会自动为其初始化为0;

静态局部变量和普通局部变量的区别

1、存储位置不同:静态局部变量存储在全局数据区,但其作用域还是局部的,静态局部变量不会因为某个子函数的完成而释放其内存空间,在其子函数外也不可调用它;

       普通局部变量存放在堆栈中,若函数中定义一个局部变量,函数执行完之后,自动释放内存,若是使用new分配的局部指针变量,存放在堆中,需要手动进行释放,采用delete;

2、默认初值不同:若是没有初始化,静态局部变量的初始值为0,由于静态局部变量的生命周期是全局的,故对其的初始化只执行一次,后面遇到合法的初始化操作会自行跳过

        若没有初始化,普通局部变量的初始值是随机的。

静态函数和普通函数的区别

主要区别还是作用域不同,静态函数的作用域是当前源文件,对该工程的其它源文件是隐藏的、不可见的。而普通函数的作用域在整个工程都是可以调用的。

静态数据成员的使用方法

静态数据成员是属于类的,而不是属于某个对象的,换句话说就是不管实例的对象有多少个,他们都共用一个静态数据成员,静态数据成员的初始化不能在类内部初始化,只能在类的外部初始化:

class A
{
private:
    int a;
    static int b;          //定义静态数据成员
public:
    A(int a):a(a){}        //数据成员初始化
};
int A::b=0;                //静态常量数据成员初始化

对于静态数据成员可以将其定义为const,但静态函数不能定义为const,对于常量的静态数据成员只能在类外时初始化。

有些书籍上说在类内初始化,但经过反复验证似乎不行(感觉和类的数据成员不能在类声明时初始化矛盾,暂时还未理解???!!!,类内部的数据成员就是一个声明,不能对变量进行初始化),经过验证,发现只能在类外初始化,和静态变量类似。代码如下:

class A
{
private:
    const static int b;          //声明
public:
    void show()
    {
        cout<<A::b<<endl;
    }
};
const int A::b=22;              //初始化

从上面的初始化过程可以看出,静态变量是属于类的,而不是某个对象,也可以说:不同的对象都用同一份静态变量成员。静态数据变量有以下两个特点:

1、即使没有对象,仍然可以访问静态数据成员

2、静态数据成员存储在全局数据区中,因此静态数据成员定义时需要分配空间,所以不能再类声明中初始化。

静态成员函数的使用

静态成员函数的使用与静态数据成员类似,静态成员函数也是属于类的,是类的一部分,不属于某个对象,是类的对象所共享的一个函数。普通成员函数都隐含的一个this指针,但静态成员函数是属于类的,故没有this指针这一说,没有this指针,静态函数也就无法访问普通的数据成员,只能访问静态数据成员。

参考程序如下:(设计了一个点的类:显示纵坐标和横坐标、显示实例了几个对象)

#include<iostream>
using namespace std;
class A
{
private:
    int x;
    int y;
    static int cnt;
public:
    A(int x,int y):x(x),y(y)
    {
        cnt++;
    }
    void show()
    {
        cout<<"这个点的坐标是:"<<x<<","<<y<<endl;
    }
    static void show_cnt()
    {
        cout<<"绘制了第"<<cnt<<"个点"<<endl;
        //cout<<x<<y<<endl;    //静态函数不能访问非静态变量
    }
};
int A::cnt=0;                  //静态数据成员初始化
int main()
{
    int x = 0;
    int y = 0;
    while(1)
    {
        if(x>300 && y>400)
        {
            break;
        }
        A a(x,y);
        a.show();
        a.show_cnt();          //静态函数属于类,任何对象都可以调用
        x=(x+1)*2;
        y=(y+1)*2;
    }
    return 0;
}

总结:静态成员函数可以被该类的所有对象访问

   静态成员函数本身只能访问静态成员

静态对象和单例模型

静态对象

将对象定义为静态的,如上面的程序如果将对象定义为静态的,即:static A a(x,y);其运行结果则是只能实例一个对象。

利用静态成员实现单例模型

将类中数据成员除构造函数外都定义成static,构造函数的属性定义为private,这样就无法在类外实例对象,静态函数在类中只有一份,也就变相的实现了只能实例一个对象。

#include<iostream>
using namespace std;
class A
{
private:
    static int cnt;
    static A *s_list;
    A() {}                     //私有构造函数,只能在类中进行对象的实例
public:
    static A* new_list();      //定义一个public函数,通过调用该函数构建对象
    void delete_list();
    static void show()
    {
        cout<<"cnt="<<cnt<<endl;
    }
};
int A::cnt=0;                  //静态数据成员初始化
A* A::s_list=NULL;

A* A::new_list()
{
    if(s_list==NULL)
    {
        s_list=new A;
    }
    cnt++;
    return s_list;
}
void A::delete_list()          //用来删除对象,释放空间
{
    if(--cnt==0)
    {
        delete this;
    }
}
int main()
{
    A* s1=A::new_list();
    cout<<hex<<s1<<endl;
    A::show();

    A* s2=A::new_list();
    cout<<hex<<s1<<endl;
    A::show();
    return 0;
}

 

运行结果:

00352B48
cnt=1
00352B48
cnt=2

 

posted @ 2017-12-20 01:05  影-辰  阅读(203)  评论(0编辑  收藏  举报