最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++的關(guān)鍵字之static你了解嗎

 更新時(shí)間:2022年02月25日 17:18:23   作者:小菜雞加油  
這篇文章主要為大家詳細(xì)介紹了C/C++的關(guān)鍵字之static,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

C語言

隱藏

場景演示

當(dāng)我們同時(shí)編譯多個(gè)文件時(shí),所有未加static前綴的全局變量和函數(shù)都具有全局可見性。會(huì)導(dǎo)致符號表認(rèn)為存在同名全局變量和函數(shù)發(fā)生碰撞。

場景:全局的變量/函數(shù)在.h中會(huì)在多個(gè).cc文件中擁有且全局可見有鏈接問題。

image-20220221183611526

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

運(yùn)行結(jié)果

image-20220221183828906

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

image-20220221183926498

image-20220221183944564

可以看到雙方的.o符號表中都認(rèn)為有一個(gè)GLOBAL全局函數(shù)的Test,兩者匯編階段形成的符號表此時(shí)在匯總的階段就會(huì)產(chǎn)生同名全局函數(shù)沖突。

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

image-20220221184323225

解決方法

聲明和定義分離

養(yǎng)成聲明和定義分離的習(xí)慣,在.h中只聲明不定義。在.c文件中定義。

image-20220221184956320

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

image-20220221185142988

為什么此時(shí)就可以正常運(yùn)行了?

依然查看符號表,可以發(fā)現(xiàn)b.o和c.o中此時(shí)只是給Test聲明留了一個(gè)全局的NOTYPE位置。

image-20220221185244568

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

image-20220221185352451

最后三個(gè).o文件鏈接的時(shí)候確定Test()實(shí)際在最后生成的.out文件中的虛擬內(nèi)存地址。運(yùn)行時(shí)加載到內(nèi)存中,之后的詳細(xì)過程就是linux創(chuàng)建進(jìn)程中的事情。

image-20220221185617070

使用static關(guān)鍵字及缺陷

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

a.h

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

代碼結(jié)構(gòu)

image-20220221185854507

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

image-20220221185942306

此時(shí)反匯編查看Test()函數(shù)地址。我們發(fā)現(xiàn)此時(shí)生成了兩個(gè)test函數(shù),不過函數(shù)地址不同。

結(jié)論:static函數(shù)作用域僅在自己所在文件,其實(shí)是編譯后不同文件下的同名static函數(shù)會(huì)有不同的內(nèi)部命名

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

image-20220221190131277

既然生成了兩份,我們就可以發(fā)現(xiàn),如果是一個(gè)靜態(tài)的全局變量,我們分別進(jìn)行修改實(shí)際上對兩個(gè)不同的變量進(jìn)行修改的。如果要解決全局變量統(tǒng)一性訪問,保證全局變量不可變即可。另外一種方式就是使用單例模式。

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);
}

image-20220221195458359

保持變量內(nèi)容的持久

  • 全局靜態(tài)變量

在全局變量前加上關(guān)鍵字static,全局變量就定義成一個(gè)全局靜態(tài)變量。

內(nèi)存中位置:靜態(tài)存儲區(qū),在整個(gè)程序運(yùn)行期間移植存在。

初始化:未經(jīng)初始化的全局靜態(tài)變量會(huì)被自動(dòng)初始化為0(自動(dòng)對象的值是任意的,除非他是被顯示初始化)。

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

  • 局部靜態(tài)變量

內(nèi)存位置:靜態(tài)存儲區(qū)

初始化:未經(jīng)初始化的局部靜態(tài)變量會(huì)被自動(dòng)初始化為0(自動(dòng)對象的值是任意的,除非他是被顯示初始化)。

作用域:為局部作用域,當(dāng)定義他的函數(shù)或者語句塊結(jié)束時(shí),作用域結(jié)束。但是當(dāng)局部靜態(tài)變量離開作用域后,并沒有被銷毀,依然駐留在內(nèi)存中,只不過我們不能再對它進(jìn)行訪問,直到該函數(shù)再次被調(diào)用,并且值不變。

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

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

默認(rèn)初始化為0

默認(rèn)初始化為0:在靜態(tài)存儲區(qū),內(nèi)存中所有的字節(jié)默認(rèn)值都是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的類成員稱為類的靜態(tài)成員,用static修飾的成員變量,稱之為靜態(tài)成員變量;靜態(tài)的成員變量一定要在類外進(jìn)行初始化。

  • 靜態(tài)變量屬于整個(gè)類,所有對象,生命周期在整個(gè)程序間運(yùn)行
  • 在類成員函數(shù)中,可以隨便訪問

static類成員方法

用static修飾的成員函數(shù),稱之為靜態(tài)成員函數(shù)。(因?yàn)樵摮蓡T變量沒有this指針)

static成員函數(shù),沒有this指針,不使用對象就可以調(diào)用–>fun::。

靜態(tài)成員函數(shù)可以調(diào)用非靜態(tài)成員函數(shù)(/成員)嗎?不行。沒有this指針

非靜態(tài)成員函數(shù)可以調(diào)用類的靜態(tài)成員函數(shù)嗎?可以

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()
            //類里面是一個(gè)整體都在類域中,類里面不受訪問限定符限制
        }
    	static void f4()
        {
        }
private:
};

單例模式

  • 單例模式

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

1.如何保證全局(一個(gè)進(jìn)程中)只有一個(gè)唯一的實(shí)例對象

參考只能在堆上創(chuàng)建對象和在棧上創(chuàng)建對象,禁止構(gòu)造和拷貝構(gòu)造及賦值。

提供一個(gè)GetInstance獲取單例對象。

2.如何提供只有一個(gè)實(shí)例呢?

餓漢模式和懶漢模式。

3.使用場景

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

具體的單例模式在特殊類設(shè)計(jì)中提及。

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!   

相關(guān)文章

  • C++實(shí)現(xiàn)xml解析器示例詳解

    C++實(shí)現(xiàn)xml解析器示例詳解

    這篇文章主要為大家介紹了C++實(shí)現(xiàn)xml解析器示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • C++ 隨機(jī)數(shù)字以及隨機(jī)數(shù)字加字母生成的案例

    C++ 隨機(jī)數(shù)字以及隨機(jī)數(shù)字加字母生成的案例

    這篇文章主要介紹了C++ 隨機(jī)數(shù)字以及隨機(jī)數(shù)字加字母生成的案例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • c++靜態(tài)局部變量和靜態(tài)函數(shù)示例

    c++靜態(tài)局部變量和靜態(tài)函數(shù)示例

    這篇文章主要介紹了c++靜態(tài)局部變量和靜態(tài)函數(shù)示例,需要的朋友可以參考下
    2014-04-04
  • C++基礎(chǔ)知識總結(jié)

    C++基礎(chǔ)知識總結(jié)

    本文給大家匯總介紹了C++的一些基礎(chǔ)知識,不管是對新手還是老鳥都有些幫助,希望大家能夠喜歡
    2017-05-05
  • C++ deque/queue/stack的底層原理解析

    C++ deque/queue/stack的底層原理解析

    這篇文章主要介紹了C++ deque/queue/stack的底層原理解析,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • VC6.0打開文件以及向工程中添加文件時(shí)程序崩潰自動(dòng)退出解決方法

    VC6.0打開文件以及向工程中添加文件時(shí)程序崩潰自動(dòng)退出解決方法

    vc6.0程序中,點(diǎn)擊打開文件以及向工程中添加文件時(shí),程序竟然崩潰自動(dòng)退出了,不知什么原因,安裝相同的vc程序,本本竟然出現(xiàn)此緣故
    2013-01-01
  • C/C++ 讀取16進(jìn)制文件的方法

    C/C++ 讀取16進(jìn)制文件的方法

    下面小編就為大家?guī)硪黄狢/C++ 讀取16進(jìn)制文件的方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • C++中的運(yùn)算符和表達(dá)式

    C++中的運(yùn)算符和表達(dá)式

    這篇文章主要介紹了C++中的運(yùn)算符和表達(dá)式,學(xué)習(xí)使用表達(dá)式,對數(shù)據(jù)類型進(jìn)行處理.詳細(xì)介紹內(nèi)容需要的小伙伴可以參考下面文章相關(guān)內(nèi)容
    2022-03-03
  • C++對象的動(dòng)態(tài)建立與釋放詳解

    C++對象的動(dòng)態(tài)建立與釋放詳解

    我們知道可以用new運(yùn)算符可以動(dòng)態(tài)的分配內(nèi)存,用delete運(yùn)算符可以釋放這些內(nèi)存。當(dāng)我們使用new運(yùn)算符動(dòng)態(tài)的分配一個(gè)內(nèi)存之后,會(huì)自動(dòng)返回一個(gè)該內(nèi)存段的起始地址,也就是指針。
    2013-10-10
  • C++強(qiáng)制類型轉(zhuǎn)換的四種方式

    C++強(qiáng)制類型轉(zhuǎn)換的四種方式

    本文主要介紹了C++強(qiáng)制類型轉(zhuǎn)換的四種方式,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05

最新評論

通海县| 普宁市| 广汉市| 冷水江市| 巴东县| 湟源县| 清丰县| 宝兴县| 新巴尔虎左旗| 邛崃市| 崇礼县| 安宁市| 兴义市| 墨玉县| 墨玉县| 霍林郭勒市| 河东区| 银川市| 潼南县| 青阳县| 阿合奇县| 雷山县| 阳西县| 海门市| 陆丰市| 凤山县| 镇原县| 洪洞县| 玉林市| 东阿县| 疏勒县| 合山市| 铅山县| 舞阳县| 密山市| 金溪县| 涟源市| 海南省| 观塘区| 富源县| 莱芜市|