C++中static關鍵字
首先說一下之前對static的認識吧。
之前就知道static是靜態的關鍵字,可以作用於變數、函式、類成員。並且static修飾的變臉為去全域性資料區。
最近為了複習,準備校招又對static進行了複習,上網查了些資料。經過一段的思考後又有不少的收穫,所以還是要不斷的學習呀。下面就接下網上搜到的,說一說static的用法的。
首先我們要有一個這個瞭解,static變數位於全域性資料區(全域性變臉也在全域性資料區),也就是說static變數的“生命週期”是整個程式,但是static變數的訪問許可權沒有發生改變。
1、static區域性變數 VS 普通區域性變數
在函式內部的static區域性變數在函式被第一次呼叫時初始化一次,下次在呼叫這個函式時不會重新為變數分配記憶體進行初始化,仍然使用的上一次建立的變數。出了函式作用域,static區域性變數沒有被銷燬(因為它在全域性資料區)。但是不能在函式作用域之外訪問(因為它是一個區域性變數)。
普通的區域性變數是存放在棧區的,過了作用域就會被銷燬掉。
程式碼:
#include<iostream>
#include<string>
using namespace std;
void foo(int b)
{
static int a = 3;
cout << "a = " << a << "; b = " << b;
a += b;
cout << "; a += b後:" << a << endl;
}
int main()
{
foo(2);//第一次呼叫foo
foo(1);//第二次呼叫foo,使用上一次建立的變數a
return 0;
}
結果:
通過結果我們可以看出來第一次呼叫foo時,為區域性static變數a申請記憶體,並初始化為3,然後執行a+=2,後a=5;第二次呼叫foo時,之前a的記憶體沒有銷燬掉(因為a存放在全域性資料區),執行了a+=1後變為6.
那麼我們總結一下,靜態區域性變數的特點(括號內為note:2,也就是區域性變數的對比):
(1)該變數在全域性資料區分配記憶體(區域性變數在棧區分配記憶體);
(2)靜態區域性變數在程式執行到該物件的宣告處時被首次初始化,即以後的函式呼叫不再進行初始化(區域性變數每次函式呼叫都會被初始化);
(3)靜態區域性變數一般在宣告處初始化,如果沒有顯式初始化,會被程式自動初始化為0(區域性變數不會被初始化);
(4)它始終駐留在全域性資料區,直到程式執行結束。但其作用域為區域性作用域,也就是不能在函式體外面使用它(區域性變數在棧區,在函式結束後立即釋放記憶體);
2、在某個檔案中的static全域性變數 VS 普通全域性變數
在檔案開始的地方定義的變數為全域性變數,全域性static變數。
static int i = 1; //全域性static變數
int j = 1; //全域性變數
全域性變數和全域性static變數的區別在於,全域性static不能跨檔案使用,而全域性變數可以跨檔案使用。
case1如下,在a.c檔案中有一個全域性變數,在檔案b.c中使用extern關鍵字就可以使用這個全域性變數了。
//檔案 a.c 中
int n = 15; //全域性變數
//檔案 b.c中
#include <stdio.h>
extern int n;
void fn()
{
n++;
printf("after: %d\n",n);
}
void main()
{
printf("before: %d\n",n);
fn();
}
輸出為:before: 15after: 16
case2:在檔案a.c中有一個全域性static變數,在檔案b.c中使用extern關鍵字,但仍然不能使用這個全域性static變數。
//檔案 a.c
static int n = 15; //全域性static變數
//檔案 b.c
#include <stdio.h>
extern int n;
void fn()
{
n++;
printf("after: %d\n",n);
}
void main()
{
printf("before: %d\n",n);
fn();
}
此時,會出現undeference to "n"的錯誤。全域性static使用extern跨檔案使用。
3、某個檔案內的static函式 VS 普通函式
這個類似於全域性變數和全域性static變數。static函式不能跨檔案使用。
檔案a.c中的static函式,不能使用extern在b.c檔案中使用;
a.c中的普通函式,可以使用extern在b.c中使用;
4、static成員變數 VS 普通成員變數
類中的static成員變數不屬於類的某個特定的instance,而是出於整個class,被類的所有物件共享。無論建立多少個物件,在記憶體中只有一份(位於全域性資料區)。
而類的普通成員變數是屬於某個instance的,建立多少個物件,就會有多少個記憶體來存放這個變數(位於棧上)。普通成員變數,屬於某個instance。
類名::變數名;
5、static成員函式 VS static普通函式
static成員函式與static成員變數類似,屬於類,而不會屬於類的某一個特定例項。static成員函式沒有this指標。
普通成員函式,在函式形參的第一個位置隱藏了一個&obj,相當於是將這個函式與obj物件繫結在一起,this指標。普通成員函式屬於類的某一個例項。
靜態成員函式有特點
1.靜態成員之間可以相互訪問,包括靜態成員函式訪問靜態資料成員和訪問靜態成員函式;
2.非靜態成員函式可以任意地訪問靜態成員函式和靜態資料成員;
3.靜態成員函式不能訪問非靜態成員函式和非靜態資料成員;
4.呼叫靜態成員函式,可以用成員訪問操作符(.)和(->)為一個類的物件或指向類物件的指標呼叫靜態成員函式,也可以用類名::函式名呼叫(因為他本來就是屬於類的,用類名呼叫很正常)
類名::函式名(實參);
相關文章
- 【轉】C++ static關鍵字C++
- java中的static關鍵字Java
- static關鍵字
- final關鍵字和static關鍵字
- java中static關鍵字的作用Java
- java中的static和final關鍵字Java
- static關鍵字---"工具類"
- static關鍵字的作用
- 初識static關鍵字
- Java 的 static 關鍵字Java
- PHP中static與yield關鍵字的思考PHP
- C語言之static關鍵字C語言
- 說說iOS中的常用的關鍵字static ,class(僅限Swift關鍵字)iOSSwift
- 深入理解Swift中static和class關鍵字Swift
- 第五章 static關鍵字
- 1_static關鍵字的使用
- C++中的 const 關鍵字C++
- PHP static 關鍵字和 self 關鍵字例項化的區別PHP
- c語言static關鍵字的理解C語言
- iOS常用關鍵字static、const、extern、defineiOS
- Java基礎——final和static關鍵字Java
- C語言中static關鍵字詳解C語言
- JAVA面試題 淺析Java中的static關鍵字Java面試題
- explicit關鍵字【C++】C++
- C++關鍵字decltypeC++
- Java基礎-static關鍵字和單例模式Java單例模式
- final與static關鍵字的區別?(skycto JEEditor)
- 一次性帶你弄懂java中的static關鍵字Java
- c/c++ const關鍵字C++
- 你真的瞭解JAVA中物件和類、this、super和static關鍵字嗎Java物件
- Java課堂篇4_關鍵字this、static的理解Java
- 【C++】requires關鍵字簡介C++UI
- C++ typeid關鍵字詳解C++
- C++ explicit&noexcept關鍵字C++
- C++ 定義靜態成員 static 關鍵字不能在定義出重複出現C++
- Java開發筆記(五十五)關鍵字static的用法Java筆記
- 詳解C++的模板中typename關鍵字的用法C++
- C++ 62個關鍵字的作用C++
- C++關鍵字(持續更新ing)C++