static关键字总结

static,顾名思义就是静态的,当我们用static修饰变量或者函数时,那么所修饰的变量或者函数也就成了静态变量或者静态函数。那么静态变量与普通变量有什么区别呢,静态函数与普通函数又有什么区别呢?staticC++中又有什么特殊的用法呢?下面就这几方面简单的总结一下:

1、static变量

   通常我们在函数体内定义变量时,编译器使得每次函数调用时堆栈的指针向下移动一个适当的位置,为创建的变量分配内存。 如果我们定义时就初始化了该变量,那么每次调用这个函数时都会重新初始化该变量。但是,如果我们想在两次调用函数时保留变量的值怎么办呢?当然我们自然而然会想到全局变量,这样当然能解决我们上面说的问题,但是同时又存在另一个问题,那就是这个变量不只属于这个函数,它不仅仅受这个函数控制。这时static变量就能很好的解决上面的问题,C语言与C++都允许在函数内部创建一个static对象,这个对象不是存储在堆栈上 ,而是存储在静态存储区上。Static变量只会在函数第一次调用时初始化一次,以后再次调用时会保持它之前的值。下面的例子就说明了这一特性:

void StaticTest()

{

static int iVal = 1;//只有第一次进行了初始化

cout << iVal << " ";

iVal++;

}

int main()

{

for (int i=0; i<5; ++i)

{

StaticTest();

}

//iVal = 4;//未声明的标识符iVal

return 0;

}

上例就可以看到StaticTest()中的iVal变量就是一个静态变量,当我们第一次调用时初始化为1,当后面再次调用时就没有再次初始化,只是使用上次保存的值,在整个程序运行中都一直存在,所以上例中会连续输出1 2 3 4 5,而不是5个连续的1,同时下面我们如果要使用iVal时却又不可以使用,因为它只属于StaticTest()函数,虽然它是一直存在的。

i .静态变量的初始化

  上面我们说了,上例中当第一次调用函数时,我们会把变量显示的初始化为1,但是如果我们没有显示的初始化呢?这种情况下又会发生什么事情呢?我们知道一般内置类型当我们作为局部变量使用时,编译器是不会帮我们自动初始化,而全局变量编译器会为我们初始化为该0。但是静态变量呢,它是和普通的局部变量一样,还是和全局变量相同呢,实际证明它是和全局变量一样的,即使我们没有对它初始化,但是当我们第一次使用它时还是会被初始化为0。当然上面只是说的内置类型,但是如果创建的静态对象是自定义的类型的话,那么我们自定义的对象必须有默认构造函数才行。

ii .静态对象的析构

静态对象的析构函数在程序从main()块中退出时,或者标准的C库函数exit()被调用时才会调用,静态对象的销毁是按它们初始化的相反顺序来进行的,当然只有被初始化的对象才会被初始化,未初始化的当然是不会销毁的。还有一点,文件中的全局变量总是在main()函数执行之前被创建。下例说明了该知识点:

class CStatic

{

public:

CStatic(int i = 0):m_iTest(i)

{

cout << m_iTest << endl;

}

~CStatic()

{

cout << "~CStatic() " << m_iTest << endl;

}

private:

int m_iTest;

};

void Fun1()

{

static CStatic st1(12);

}

CStatic g_static(11);

int main()

{

cout << "enter main" << endl;

Fun1();

cout << "leave main" << endl;

   return 0;

}

上例中我们看到的输入应该是

11

enter main

12

leave main

~CStatic 12

~CStatic 11

我们可以看到程序是先构造的全局变量,然后才进入main函数,所以全局变量是在main调用之前创建的,当从main函数推出时,所有创建的对象又会按创建的顺序的相反地顺序析构。

·2、类中的静态成员及成员函数

   上面讲了静态变量的相关知识,在C语言中用的较为普遍,下面我们在讲一下在C++的类中static的使用。

C++中有时我们需要为某个类的分配一个单一的存储空间,当然我们全局变量好像可以满足单一的存储空间这一要求,但是有一点确实不行的,就是全局变量并不属于我们定义的这个类,它可以被任何人修改,并且在同一个项目中它还有可能与其他变量冲突。这时候static就显示出了其特殊性,它可以像全局变量那样去存储,同时它又是仅仅属于这个类的,所以这里static是最好的选择。

刚讲了类的static数据成员是有其单一的存储空间,所以它是属于整个类的,而不属于某个对象,所以无论创建多少个对象,但是static数据成员都只有一个,同时static数据成员必须定义,并且要定义到类的外部而且只允许定义一次。

下面我们就在举个例子来说明static成员的问题:

class CBase

{

public:

static void TestFun()

{

cout << "TestFun()" << endl;

}

static const int m_ConTest = 4;

private:

//static int m_Test = 3;// 只能初始化静态常量成员

static int m_Test;

};

 int CBase::m_Test = 3;

class CSub:public CBase

{

};

int main()

{

CSub sub;

sub.TestFun();//子类继承了父类的静态成员

int i = sub.m_ConTest;

cout << i << endl;

CBase base;

//cout << base.m_Test << endl;//静态私有成员依旧是私有成员

cout << "----------------------------------" << endl;

getch();

return 0;

}

上例中CBase类中定义了一个m_Test静态成员变量,同时还定义了一个m_ConTest静态变量,我们可以看到两个唯一的区别就是一个是const的,而另一个不是,同时发现普通的静态成员变量如果在类中定义的话会报错,但是const静态变量却是可以在类中定义的,并且从上面我们还可以看到像一般的成员变量及成员函数一样,子类也是可以继承父类的静态成员的。

 我们知道在C++中如果在类中定义一个普通的常量数据成员时,实际上这个成员只对我们创建的各个对象来说是常量,实际上并非真正的常量,因为它并不是编译时常量,所以我们经常用枚举类型来创建一个编译时常量,虽然我们经常这样使用,但是实际上这样丧失了其本来的作用。所以为了更好的完成同样的事情,我们就可以像上例一样定义一个静态常量,它既是常量,同时又是静态的,所以可作为一个编译时变量使用。并且使用静态常量还有一个好处,就是枚举只能用整形值,但是静态常量却不是。

3、静态变量使用的注意点

1)、内置类型的静态变量如果没有提供一个初始值的话,编译器会确保在程序开始时把它初始化为0

2)、全局对象是在main()函数执行之前被创建的。

3)、类的静态数据成员如果被声明但没定义,编译器会报错,并且普通的静态成员要在类外定义。

4)、静态的成员函数不能访问一般的数据成员,它只能访问静态数据成员, 也只能调用其他的静态成员函数。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值