中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

C/C++的關鍵字static怎么使用

發布時間:2022-02-26 19:09:36 來源:億速云 閱讀:346 作者:iii 欄目:開發技術

這篇文章主要介紹“C/C++的關鍵字static怎么使用”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“C/C++的關鍵字static怎么使用”文章能幫助大家解決問題。

    C語言

    隱藏

    場景演示

    當我們同時編譯多個文件時,所有未加static前綴的全局變量和函數都具有全局可見性。會導致符號表認為存在同名全局變量和函數發生碰撞。

    場景:全局的變量/函數在.h中會在多個.cc文件中擁有且全局可見有鏈接問題。

    C/C++的關鍵字static怎么使用

    a.h

    #pragma once
    #include<stdio.h>
    void Test()
    {
      printf("I am test..\n");
    }

    b.c

    #include"a.h"
    void call()
    {
        Test();
    }

    c.c

    #include"a.h"
    int main()
    {
       Test();   
    }

    makefile

    all:c
    c:c.o b.o
    	gcc -o $@ $^ 
    c.o:c.c
    	gcc -c $^ 
    b.o:b.c
    	gcc -c $^ 
    .PHONY:clean
    clean:
    	rm -rf *.o c

    運行結果

    C/C++的關鍵字static怎么使用

    此時查看b.oc.o符號表。(readelf -s xxx.o)

    C/C++的關鍵字static怎么使用

    C/C++的關鍵字static怎么使用

    可以看到雙方的.o符號表中都認為有一個GLOBAL全局函數的Test,兩者匯編階段形成的符號表此時在匯總的階段就會產生同名全局函數沖突。

    此時在兩者的二進制文件里都認為各自擁有Test()函數,且都在全局。而全局函數只能有一個名字(注:重載是底層重新命名了)。雖然我們知道兩個Test()是同一個,但是link的時候認為有兩個同名函數實現,因此報link錯。

    C/C++的關鍵字static怎么使用

    解決方法

    聲明和定義分離

    養成聲明和定義分離的習慣,在.h中只聲明不定義。在.c文件中定義。

    C/C++的關鍵字static怎么使用

    a.h

    #include<stdio.h>
    void Test();

    a.c

    #include"a.h"
    void Test()
    {
        cout<<"I am test..."<<endl;
    }

    makefile

    all:c
    c:c.o b.o a.o
    	gcc -o $@ $^ 
    c.o:c.c
    	gcc -c $^ 
    b.o:b.c
    	gcc -c $^ 
    a.o:a.c
    	gcc -c $^ 
    .PHONY:clean
    clean:
    	rm -rf *.o c

    C/C++的關鍵字static怎么使用

    為什么此時就可以正常運行了?

    依然查看符號表,可以發現b.o和c.o中此時只是給Test聲明留了一個全局的NOTYPE位置。

    C/C++的關鍵字static怎么使用

    而在a.o中定義Test(),因此a.o中是func類型。

    C/C++的關鍵字static怎么使用

    最后三個.o文件鏈接的時候確定Test()實際在最后生成的.out文件中的虛擬內存地址。運行時加載到內存中,之后的詳細過程就是linux創建進程中的事情。

    C/C++的關鍵字static怎么使用

    使用static關鍵字及缺陷

    那如果我就是想要直接在.h中存放一個公共的全局的對象來供其他所有文件使用呢?使用static關鍵字。

    a.h

    #pragma once
    #include<stdio.h>
    static void Test()
    {
      printf("I am test..\n");
    }

    代碼結構

    C/C++的關鍵字static怎么使用

    此時為什么又成立呢?兩者.o文件中為什么對同名的全局函數包容了呢?可以看到此時兩者的符號表中仍然是func,按照場景演示中的例子,應該報錯的。

    C/C++的關鍵字static怎么使用

    此時反匯編查看Test()函數地址。我們發現此時生成了兩個test函數,不過函數地址不同。

    結論:static函數作用域僅在自己所在文件,其實是編譯后不同文件下的同名static函數會有不同的內部命名

    不同.c文件include了static變量之后該變量只在各自包含該變量的.c中可見。

    C/C++的關鍵字static怎么使用

    既然生成了兩份,我們就可以發現,如果是一個靜態的全局變量,我們分別進行修改實際上對兩個不同的變量進行修改的。如果要解決全局變量統一性訪問,保證全局變量不可變即可。另外一種方式就是使用單例模式。

    a.h

    #pragma once
    #include<stdio.h>
    static int a =0;

    b.h

    #include"a.h"
    void call();

    b.c

    #include"b.h"
    void call()
    {
       a = 1;
       printf("a=%d\n",a);
    }

    c.c

    #include"b.h"
    int main()
    {
       a=2;
       printf("a=%d\n",a); 
       call();
       printf("a=%d\n",a);
    }

    C/C++的關鍵字static怎么使用

    保持變量內容的持久

    • 全局靜態變量

    在全局變量前加上關鍵字static,全局變量就定義成一個全局靜態變量。

    內存中位置:靜態存儲區,在整個程序運行期間移植存在。

    初始化:未經初始化的全局靜態變量會被自動初始化為0(自動對象的值是任意的,除非他是被顯示初始化)。

    作用域:全局靜態變量是從定義指出開始,到文件結尾,在聲明他的文件之外是不可見的。

    • 局部靜態變量

    內存位置:靜態存儲區

    初始化:未經初始化的局部靜態變量會被自動初始化為0(自動對象的值是任意的,除非他是被顯示初始化)。

    作用域:為局部作用域,當定義他的函數或者語句塊結束時,作用域結束。但是當局部靜態變量離開作用域后,并沒有被銷毀,依然駐留在內存中,只不過我們不能再對它進行訪問,直到該函數再次被調用,并且值不變。

    如下的count變量作用域在test函數中,而生命周期是整個程序。在第一次進入test()的時候會初始化,之后進入test()就不再執行第5行代碼了。

    #include<stdio.h>
    void test()
    {
        static int count =0;
        count++;
    }
    int main()
    {
        for(int i =0 ; i < 10 ; i++ ) test();
    }

    默認初始化為0

    默認初始化為0:在靜態存儲區,內存中所有的字節默認值都是0x00。

    #include <stdio.h>
    int a;
    int main(void)
    {
        int i;
        static char str[10];
        printf("integer: %d;  string: (begin)%s(end)", a, str);
        return 0;
    }

    Cpp

    static類成員變量

    聲明為static的類成員稱為類的靜態成員,用static修飾的成員變量,稱之為靜態成員變量;靜態的成員變量一定要在類外進行初始化

    • 靜態變量屬于整個類,所有對象,生命周期在整個程序間運行

    • 在類成員函數中,可以隨便訪問

    static類成員方法

    用static修飾的成員函數,稱之為靜態成員函數。(因為該成員變量沒有this指針)

    static成員函數,沒有this指針,不使用對象就可以調用&ndash;>fun::。

    靜態成員函數可以調用非靜態成員函數(/成員)嗎?不行。沒有this指針

    非靜態成員函數可以調用類的靜態成員函數嗎?可以

    class Date
    {
        public:
        	Date(int year=0,int month=1,int day=1)
            {
            }
        	void f1()
            {
            }
        	static void f2()
            {
    		   f1();//沒有this指針
            }
        private:
    }
    class Date{
    public:
        	void f3()
            {
                f4();//突破類域+訪問限定符就可以訪問 Date::f4();/對象.f4()
                //類里面是一個整體都在類域中,類里面不受訪問限定符限制
            }
        	static void f4()
            {
            }
    private:
    };

    單例模式

    • 單例模式

    一個類只能創建一個對象,即單例模式,該模式可以保證系統中該類只有一個實例,并提供一個訪問它的全局訪問點,該實例被所有程序模塊共享。比如在某個服務器程序中,該服務器的配置信息存放在一個文件中,這些配置數據由一個單例對象統一讀取,然后服務進程中的其他對象再通過這個單例對象獲取這些配置信息,這種方式簡化了在復雜環境下的配置管理。

    1.如何保證全局(一個進程中)只有一個唯一的實例對象

    參考只能在堆上創建對象和在棧上創建對象,禁止構造和拷貝構造及賦值。

    提供一個GetInstance獲取單例對象。

    2.如何提供只有一個實例呢?

    餓漢模式和懶漢模式。

    3.使用場景

    由于全局的變量在.h中會在多個.cc文件中擁有且可見容易有鏈接問題。而static又只能在當前文件可見。因此真要處理成全局的就使用單例模式。

    具體的單例模式在特殊類設計中提及。

    關于“C/C++的關鍵字static怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    c c++
    AI

    榆树市| 阿拉尔市| 上虞市| 陇南市| 和林格尔县| 临安市| 高邮市| 右玉县| 鄂州市| 象山县| 台中市| 株洲县| 临泉县| 陆川县| 怀仁县| 凉城县| 新乡市| 黄冈市| 延川县| 文化| 大荔县| 白水县| 华阴市| 五常市| 上栗县| 桐柏县| 高邮市| 津南区| 禄丰县| 南漳县| 台南市| 湛江市| 萍乡市| 尖扎县| 津市市| 汾西县| 桐梓县| 东城区| 林州市| 萨嘎县| 滨海县|