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關鍵字。