C++中的static關鍵字詳解

用法1:靜態全局變量

實例1:
test.cpp中
int nTest = 0;
static int nStaticTest = 1;

main.cpp中
#include <iostream>
using namespace std;

extern int nTest;
extern int nStaticTest;

void main()
{
    cout << "nTest =" << nTest << endl;
    cout << "nStaticTest =" << nStaticTest << endl;
    system("pause");
}

編譯時報錯信息:
這裏寫圖片描述
編譯時報錯,因爲靜態全局變量只在本文件中可見。全局變量可以通過extern在別的文件中使用。

實例2:
main.cpp中
#include <iostream>
using namespace std;

static int nStaticTest;

int Add()
{
    return ++nStaticTest;
}

void main()
{
    cout << "uninitialize nStaticTest = " << nStaticTest << endl;
    nStaticTest = 3;
    cout << "initialize nStaticTest = " << nStaticTest << endl;
    cout << "after add nStaticTest = " << Add() << endl;
    system("pause");
}

運行結果如下:
這裏寫圖片描述

靜態全局變量特點:
靜態全局變量和靜態函數只有在本文件內的代碼可以訪問到,在其他文件中是不可見的,在其他文件內不能通過extern訪問。
其他文件中可以定義相同名稱的變量,不會衝突。
程序開始時分配內存空間,結束時釋放內存空間。
存儲在全局數據區。全局數據區存放全局變量和static變量。默認爲0。

用法2:靜態局部變量

實例1:
main.cpp中
#include <iostream>
using namespace std;

int GetStaticValue()
{
    static int nLoopValue = 5;
    return nLoopValue--;
}

void main()
{
    int nVlaue = GetStaticValue();
    while( nVlaue > 0 )
    {
        cout << " nLoopValue = " << nVlaue << endl;
        nVlaue = GetStaticValue();
    }

    system("pause");
}

運行結果如下:
這裏寫圖片描述

靜態局部變量特點:
局部static變量,將只有唯一的一個靜態分配的對象,它被用於在該函數的所有調用中表示這個變量,這個對象將只在執行線程第一次達到它的定義時初始化。

用法3:靜態函數

實例1:
main.cpp文件
#include <iostream>
using namespace std;
static void func();

void main()
{
    func();
    system("pause");
}

void func()
{
    cout << " this is static function ! " << endl;
}

輸出結果如下:
這裏寫圖片描述

靜態函數特點:
靜態函數與普通函數不同,它只能在聲明它的文件中可見,不能被其他文件使用。
其他文件可以定義相同名字的函數,不會發生衝突。

用法4:靜態數據成員
在類內數據成員的聲明前面加上關鍵字static,該數據成員就是類內的靜態數據成員。

實例1#include <iostream>
using namespace std;
int nStatic = 2;

class CTest{
public:
    CTest( int nValue1);
    void GetStaticValue();

public:
    int nNormal;
    static int nStatic;
};

int CTest::nStatic = 0;

CTest::CTest( int nValue1 )
{
    nNormal = nValue1;
    nStatic += nNormal;
}

void CTest::GetStaticValue()
{
    cout << " nStatic = " << nStatic << endl;
}

void main()
{
    CTest::nStatic+=1;

    CTest CTest_1( 2 );
    CTest_1.GetStaticValue();

    CTest CTest_2( 3 );
    CTest_2.GetStaticValue();

    cout << " global nStatic = " << nStatic << endl;
    system("pause");
    return;
}

運行結果如下:
這裏寫圖片描述

靜態數據成員的特點:
對於非靜態數據成員,每個類對象都有自己的拷貝。靜態數據成員是該類的所有對象所共有的。對該類的多個對象來說,靜態數據成員只分配一次內存,供所有對象共用。所以,靜態數據成員的值對每個對象都是一樣的,它的值可以更新;
靜態數據成員存儲在全局數據區。靜態數據成員定義時要分配空間,所以不能在類聲明中定義。
靜態數據成員和普通數據成員一樣遵從public,protected,private訪問規則;
因爲靜態數據成員在全局數據區分配內存,屬於本類的所有對象共享,所以,它不屬於特定的類對象,在沒有產生類對象時其作用域就可見,即在沒有產生類的實例時,我們就可以操作它;
靜態數據成員初始化與一般數據成員初始化不同。靜態數據成員初始化的格式爲:
<數據類型><類名>::<靜態數據成員名>=<值>
類的靜態數據成員有兩種訪問形式:
<類對象名>.<靜態數據成員名> 或 <類類型名>::<靜態數據成員名>
靜態數據成員主要用在各個對象都有相同的某項固定屬性的時候。節省內存空間,方便修改和維護。
靜態數據成員沒有進入程序的全局名字空間,因此不存在與程序中其它全局名字衝突的可能性。

用法5:靜態成員函數
在類內成員函數的聲明前面加上關鍵字static,該成員函數就是類內的靜態成員函數。

實例1:
class CTest{
public:
    CTest( int nValue1);
    static void GetStaticValue();

public:
    int nNormal;
    static int nStatic;
};

int CTest::nStatic = 0;

CTest::CTest( int nValue1 )
{
    nNormal = nValue1;
    nStatic += nNormal;
}

void CTest::GetStaticValue()
{
    cout << " nStatic = " << nStatic << endl;
}

void main()
{
    CTest CTest_1( 2 );
    CTest_1.GetStaticValue();

    system("pause");
    return;
}

運行結果如下:
這裏寫圖片描述

靜態成員函數特點:
它爲類的全部服務而不是爲某一個類的具體對象服務。
因爲普通成員函數總是具體的屬於某個類的具體對象的,普通的成員函數一般都隱含了一個this指針,this指針指向類的對象本身。靜態成員函數由於不是與任何的對象相聯繫,因此它不具有this指針。因此靜態成員函數與類的全局函數相比速度上會有少許的增長。
靜態成員之間可以相互訪問,包括靜態成員函數訪問靜態數據成員和訪問靜態成員函數。
非靜態成員函數可以任意地訪問靜態成員函數和靜態數據成員。
靜態成員函數不能訪問非靜態成員函數和非靜態數據成員。
調用靜態成員函數,可以用成員訪問操作符(.)和(->)爲一個類的對象或指向類對象的指針調用靜態成員函數,也可以直接使用如下格式:<類名>::<靜態成員函數名>(<參數表>)調用類的靜態成員函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章