四種對象生存期和做用域、static 用法總結

1、四種對象生存期和做用域ios


棧對象
編程

隱含調用構造函數(程序中沒有顯式調用)安全

堆對象
函數

隱含調用構造函數(程序中沒有顯式調用),要顯式釋放spa

全局對象、靜態全局對象
線程

全局對象的構造先於main函數對象

已初始化的全局變量或靜態全局對象存儲於.data段中ci

未初始化的全局變量或靜態全局對象存儲於.bss段中作用域

靜態局部對象
it

已初始化的靜態局部變量存儲於.data段中

未初始化的靜態局部變量存儲於.bss段中

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 
#include <iostream>
using namespace std;

class Test
{
public:
    Test(int n) : n_(n)
    {
        cout << "Test " << n_ << " ..." << endl;
    }
    ~Test()
    {
        cout << "~Test " << n_ << " ..." << endl;
    }
private:
    int n_;
};

int n;          // 未初始化的全局變量,初始值爲0。n存儲於.bss段中。(block started by symbol)
int n2 = 100;   // 已初始化的全局變量,初始值爲100。n2存儲於.data段中。
Test g(100);        // 全局對象的構造先於main函數
static Test g2(200);

int main(void)
{
    cout << "Entering main ..." << endl;

    Test t(10);     // 棧上建立的對象,在生存期結束的時候自動釋放
    {
        Test t(20);
    }

    {
        Test *t3 = new Test(30);        // 堆上建立的對象,要顯式釋放
        delete t3;
    }

    {
        static int n3;          // n3存儲於.bss段中      (編譯期初始化)
        static int n4 = 100;    // n4存儲於.data段中 (編譯期初始化)

        static Test t4(333);    // t4對象運行期初始化   .data段
    }
    cout << "Exiting main ..." << endl;
}



2、static 用法總結

1. 用於函數內部修飾變量,即函數內的靜態變量。這種變量的生存期長於該函數,使得函數具備必定的「狀態」。使用靜態變量的函數通常是不可重入的,也不是線程安全的,好比strtok(3)。
2. 用在文件級別(函數體以外),修飾變量或函數,表示該變量或函數只在本文件可見,其餘文件看不到也訪問不到該變量或函數。專業的說法叫「具備internal linkage」(簡言之:不暴露給別的translation unit)。
C語言的這兩種用法很明確,通常也不容易混淆。

因爲C++引入了類,在保持與C語言兼容的同時,static關鍵字又有了兩種新用法:
3.用於修飾類的數據成員,即所謂「靜態成員」。這種數據成員的生存期大於class的對象(實例/instance)。靜態數據成員是每一個class有一份,普通數據成員是每一個instance 有一份。
4. 用於修飾class的成員函數,即所謂「靜態成員函數」。這種成員函數只能訪問靜態成員和其餘靜態成員函數,不能訪問非靜態成員和非靜態成員函數。

 

參考:

C++ primer 第四版 Effective C++ 3rd C++編程規範

相關文章
相關標籤/搜索