C/C++ static 關鍵字

記得曾經有同事碰到一個在這樣的問題,他在頭文件中定義了一個static變量,原本是在多個源碼文件中共享,卻發現在一個源文件中賦值了,卻發現在另一個源文件中發下還是空指針。大致的代碼如下:

test.h

#ifndef _TEST_H_
#define _TEST_H_
static typeName* m_Test = new TypeName();

...
#endif
test1.c 
#include "test.h"

void test1()
{
	m_Test->some_var = "xxxxx";
}
test2.c
#include <stdio.h>
#include "test.h"

void test2()
{
	printf("%s",m_Test->some_var);
}
test.c
#include <stdio.h>

int main(int argc,char* argv[])
{
	test1();
	test2();
}
結果卻發現並沒有打印出他想要的值"xxxxx",他很不解。爲了給他解釋原因,在vs2010中新建一個win32 project。添加下面的這些代碼:

test.h

#ifndef _TEST_H_
#define _TEST_H_

static int tt = 3;

void test1();
void test2();

#endif //_test_h_
test1.cpp
#include "stdafx.h"
#include "test.h"

void test1()
{
	printf("test1 var tt address is %08x\n",&tt);
	tt = 8; //修改tt變量的值,測試是否會影響test2中的變量tt
	printf("test1 var tt value is %d\n",tt);
}
test2.cpp
#include "stdafx.h"
#include "test.h"

void test2()
{
	printf("test2 var tt address is %08x\n",&tt);
	printf("test2 var tt value is %d\n",tt);
}
test.cpp
#include "stdafx.h"
#include "test.h"
int _tmain(int argc, _TCHAR* argv[])
{
	test1();
	test2();
	return 0;
}
測試的結果輸出爲
test1 var tt address is 00a2b000
test1 var tt value is 8
test1 var tt address is 00a2b004
test1 var tt value is 3

從上面的結果可以看出變量test1中的tt變量和test2中的tt變量並不是同一個,所以test1中修改了tt的值並不會影響到test2中的tt的值。具體原因就得說說C語言中static關鍵字聲明的變量的作用域了。在C語言中,static可用來聲明全局變量,也可用來聲明局部變量。但是不管是全局變量還是局部變量,static聲明的變量的值都存儲在全局數據區,一般static變量在聲明時就要初始化,若未出世程序會自動給初始值0。

static聲明的全局變量的作用域是從聲明處開始到文件結束。修改test1.c和test2.c文件就:

test1.cpp

#include "stdafx.h"
#include "test.h"

static int xx = 8;

void test1()
{
	printf("test1 var tt address is %08x\n",&tt);
	tt = 8; //修改tt變量的值,測試是否會影響test2中的變量tt
	printf("test1 var tt value is %d\n",tt);
}
test2.cpp
#include "stdafx.h"
#include "test.h"

void test2()
{
	printf("xx value %d",xx);//這裏會提示xx變量未定義
	printf("test2 var tt address is %08x\n",&tt);
	printf("test2 var tt value is %d\n",tt);
}

前面提到的按個同事說犯的錯誤也正是因爲這個原因導致的,在test.h文件中聲明的變量被test1.cpp和test2.cpp文件都包含了。所有在test1.cpp和test2.cpp文件中都會有一個單獨的tt變量。並不會達到共享的原因。

static聲明局部變量可以先看下面一段代碼:

void test()
{
	static int var = 10;
	printf("var is %d\n",var);
	var++;
}

int main(int argc,char* argv[])
{
	test();
	test();
	test();
}
打印的結果是:
var is 10
var is 11
var is 12

why? 靜態局部變量保存在全局數據區,而不是保存在棧中,每次的值保持到下一次調用,直到下次賦新值。


C++ 中static關鍵字

在文件中static聲明的變量和函數中聲明的局部變量作用跟C語言中是一樣的,多的是在類中使用static 聲明的變量表示這個變量是屬於類的,所有該類的對象實例共享同一個static變量。值得注意的是靜態數據成員定義時要分配空間,所以不能在類聲明中定義。static聲明的類成員初始化格式是這樣的 <數據類型><類名>::<靜態數據成員名>=<值>,在初始化的時候不需要加上static關鍵字。訪問類的static成員形式如下<類類型名>::<靜態數據成員名>。


同樣,可以聲明static成員函數,所有類的對象實例共享同一個static成員函數。靜態成員函數與靜態數據成員一樣,都是類的內部實現,屬於類定義的一部分。普通的成員函數一般都隱含了一個this指針,this指針指向類的對象本身,因爲普通成員函數總是具體的屬於某個類的具體對象的。通常情況下,this是缺省的。如函數fn()實際上是this->fn()。但是與普通函數相比,靜態成員函數由於不是與任何的對象相聯繫,因此它不具有this指針。從這個意義上講,它無法訪問屬於類對象的非靜態數據成員,也無法訪問非靜態成員函數,它只能調用其餘的靜態成員函數。類中static的成員函數在定義的時候並不需要static關鍵字。




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