程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C++靜態變量內存分配,編譯階段,解密

C++靜態變量內存分配,編譯階段,解密

編輯:關於C語言

注意:

C++靜態成員變量是用static修飾的成員變量,不屬於對象的一部分,而是類一部分,因此可以在沒有實例化任何對象的時候使用靜態成員變量。但是必須初始化它。

之所以必須初始化它是因為:全局靜態變量自動初始化,但是局部變量


由於靜態變量只能被初始化一次,所以初始化成員變量不要放在如下地方:1.類的構造函數構造函數可能多次被調用);2.頭文件中頭文件可能被包含入多個地方,也可能被執行多次)。應該放在應用程序中,類以外的任何地方初始化,例如:在main中,或全局函數中,或任何函數之外:


所有的對象(不僅僅是靜態對象)初始化都只有一次
因為a初始化為1之後,一直都沒有銷毀(因為是static),所以不會再次初始化


內存分配方式有三種:  
1)從靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量,static變量。  
2)在棧上創建。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置於處理器的指令集中,效率很高,但是分配的內存容量有限。  
3)從堆上分配,亦稱動態內存分配。程序在運行的時候用malloc或new申請任意多少的內存,程序員自己負責在何時用free或delete釋放內存。動態內存的生存期由我們決定,使用非常靈活,但問題也最多。

類的靜態成員變量和函數中的靜態變量一樣,在編譯的時候就分配內存了,直到程序退出才釋放,並不是隨著對象的刪除而釋放的:

類的靜態成員變量為什麼必須得在類外初始化?


我的理解: 由於靜態變量在編譯期間必須初始化,全局變量的靜態或者非靜態的變量都可以賦初值0。而類中的變量要用構造函數來初始化,但是在編譯期間沒有創造對象,所以就沒有運行構造方法。故在編譯期間沒有給類的靜態變量初始化。所以要在類外 main之前要給該靜態變量初始化,不管該靜態變量的作用域為private還是public,因為編譯期間private沒有影響。但是一旦進入運行時,就不可以調用類中的private變量。



調用的時候可以通過對象調用,也可以通過類直接調用

class A
{
public:
int i;    //有默認值
};
class B
{
public:
static int n;
static A Aobj;
};
int B::n = 1;    //靜態成員變量的初始化
A B::Aobj;       //靜態成員變量的初始化(實例化)
void main()
{
   B Bobj;
   printf("B::n=%d Bobj.n=%d Bobj.Aobj.i=%d/n", B::n, Bobj.n, Bobj.Aobj.i);
}

私有的靜態成員變量也是放在類外初始化的.這看起來跟它的私有屬性不相符.

再做下面的測試,發現了一個有趣的現象.

class B
{
staticint i;
public:
   B(){i=3;};    //把這行注釋掉,輸出變成2
int p(){return i;};
};
int B::i = 2;      //把這行注釋掉,編譯報錯
void main()
{
   B Bobj;
   printf("private: static int B::i=%d/n", Bobj.p());    //輸出3
}

1、“這樣看來.類外的初始化那一行根本沒有起到初始化的作用.它賦的值根本沒用.(對私有靜態成員變量是這樣.公有的還是有作用的)“  這句話是不對的!!!

因為 對於static成員變量是否是private數據並沒有影響,因為設定static成員變量初值時,不受任何存取權限的束縛,

而靜態變量賦值是在編譯階段,所以早於構造函數,當類聲明對象時 i=3覆蓋了前面的值。所以才是 3

2、當把B(){i=3;};注掉時,沒有了構造函數裡的賦值覆蓋,所以結果是2 ,親測

3、因為由於靜態變量只能被初始化一次,所以放在函數體外或全局函數中


不過要注意的是,static成員變量的類型要出現在初始化語句中,因為這是初始化操作,不是賦值操作。static成員變量是在初始化而不是在類聲明時候)才定義出來的。如果沒有初始化操作,會產生鏈接錯誤

本文出自 “燃燒技術的活力” 博客,請務必保留此出處http://boyishachang.blog.51cto.com/3485129/1285956

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved