C++回顾之static用法总结、对象的存储,作用域与生存期

        在C语言中,static的用法非常简单,只有两种:

        (1)用于函数内部修饰变量,即函数内的静态变量。这种变量的生存期大于函数,使得函数具有一定的“状态”,使用静态变量的函数一般是不可重入的,也不是线程安全的。如strtok(3).

        (2) 用在文件级别,函数体外, 修饰变量或函数,表示该变量或函数只在本文件内可见。其它文件看不到也访问不到该变量或函数。

        在C++中,保留了C的上面用法,除此以外,还有以下两种新用法:

        (1) 用于修饰类的数据成员,即所谓的“静态成员”, 这种数据成员的生存期大于类对象(实例),静态数据成员是每个class有一份, 普通数据成员是每个类对象(实例)有一份。

        (2) 用于修饰类的成员函数,即所谓的“静态成员函数”,这种成员函数也只能访问静态成员和其它静态成员函数,不能访问非静态成员与非静态成员函数。


        关于对象的作用域与生存期

        需要明确一点的是,作用域与生存期在某些情况下是不一致的,它们并不等同。下面是存储器模型:

        

        程序在存储器中按上述模型存放,它有代码段,数据段,堆和栈之分。代码段是只读的,数据段分为未初始化的数据段.bss(block started by symbol)和已初始化的数据段.data段。未初始化数据段.bss的特征是在可执行文件中不占空间,在运行时才分配空间,而.data段在编译期间就被初始化,在可执行文件中占据空间。

        对于全局变量

        如int a; 未被初始化,所以它存放在.bss段中

        如int a = 100; 已初始化,故它存放在.data段中.

        对于静态全局变量

        如static int a; 未被初始化,它存放在.bss段中

        如static int a = 100; 已初始化,故它存放在.data段中


        对于静态局部变量

        如下所示:

int main()
{
    ...
    {
        //下面a,b的作用域在{}内,生存期在整个程序的生存期之内
        static int a; //存储于.bss段中
        static int b = 100; //存储于data段中。
    }
}

  

        对于全局对象与静态全局对象

        如Test g(10); static Test g(10); 它们存放在data段中,但运行时,对象的构造函数都是先于main函数调用的,在main函数结束后自动调用析构函数销毁


        对于局部对象

int main()
{
    ....
    Test t(10);//局部对象在栈上创建,生存期在main块作用域范围之内,main结束后自动调用析构函数销毁
}
        如果在以下情况,它将在{}作用域结束后就自动调用析构函数销毁

int main()
{
    ...
    {
        Test t(10);  //在栈上创建,作用域在{}
    }//退出{}后就自动销毁对象
}
        

        对于静态局部对象

        如下:

int main()
{
    ...
    {
        //均存储在data段中,作用域在{}之内,生存期在整个main结束后才自动调用析构函数销毁。
        static Test t(100); 
        
        static Test t2;
    }
}


         对于堆上的对象

        如下:

int main()
{
    ...
    {
        Test *t3 = new Test(20); //堆上创建的对象,即使跳出作用域{}也不能自动调用析构函数来释放对象。可见作用域与生存期是不同的。作用域仅仅是对象的可见范围。
        delete *t3; //主动析构。
    }
}

        总而言之,静态全局对象,全局对象,静态局部对象都存储在data段中,静态全局对象与全局对象先于main函数调用构造函数,但它们三个都在main结束后自动调用析构函数销毁对象。堆上对象创建于堆,离开作用域范围后依旧不会自动销毁,需要手动销毁对象。局部对象创建于栈上,离开作用域后自动销毁。只有全局的普通变量才区分.bss段与.data段,未被初始化的全局变量存放在.bss段中,初始化的全局变量存放在data段中,全局变量作用域在整个程序的生命周期。局部变量在栈上创建,作用域在局部。另外切记,作用域与生存期有时并不等同。



        

猜你喜欢

转载自blog.csdn.net/ab198604/article/details/19158697