C++靜態類型成員變量的初始化順序(單例模式)

對編譯器來說,靜態成員變量的初始化順序和析構順序是一個未定義的行為

#include <string>
#include <iostream>
using namespace std;
class Base{
public:static int b;static int a;};
int Base::b = 2;
int Base::a = b + 1;int main()
{Base base;cout <<"Base::a="<< Base::a << endl;cout <<"Base::b="<< Base::b << endl;return 0;
}

請添加圖片描述

6 7 18 19 行怎么修改值都一樣可見靜態類型成員變量的初始化順序和編譯器和有關
如下文所說:https://wenku.baidu.com/view/60a101842b4ac850ad02de80d4d8d15abe2300da.html
理解在?個應?程序內部,靜態變量的構造/析構順序。其中,對于全局靜態變量,視編譯器的實現?定(?種?式是根據字
母順序來決定);對于有依賴關系的,那么視依賴關系?定。?對于局部靜態變量來說,問題就開始復雜了。這也正是本?論述的重點。
?先,要理解編譯器是如何實現局部靜態變量的語法特性的。從語法上來看,局部靜態變量與全局靜態變量最?的不同在于構造時機——當
且僅當程序執?路徑?次達到局部靜態變量的定義處才出發構造。注意是?次。印象中編譯器是通過添加?個標識變量(當然這個變量?定
是全局靜態的)來實現的(即每次程序執?到時,?先檢查這個標志變量),如此來確保調?時構造且只構造?次的特性。那么反過來看局
部靜態變量的析構,編譯器會維護?個析構函數的函數指針棧,?旦構造完成,就會把相應的析構函數指針放到這個棧中。當程序結束后,
由編譯器?成的doexit函數會逐個調?這些析構函數,完成進程結束前的掃尾?作。基于此,很顯然,對于分布在程序各處的靜態局部變
量,其構造順序取決于它們在程序的實際執?路徑上的先后順序,?析構順序則正好與之相反。
很簡單,不是么?可為什么說是隱藏的坑呢,問題在于:

???是因為程序的實際執?路徑有多個決定因素(例如基于消息驅動模型的程序和多線程程序),有時是不可預知的; 另???是因為局部靜態變量分布在程序代碼各處,彼此直接沒有明顯的關聯,很容易讓開發者忽略它們之間的這種關系(這是最坑的地 ?)。

既然提出問題,那么就討論應對之道:
(1)最簡單的,避免使?局部靜態變量,將變量的聲明周期控制在開發者?中;
(2)如果確有需要,那么盡量確保局部靜態變量之間構造和析構是彼此獨?互不相關的,換句話說,它們可以以任意的順序被構造和析
構;
設計模式里的單例模式就有靜態變量互相引用從而系統奔潰。
測試程序

#include <string>
#include <iostream>
using namespace std;
class Log
{
public:static Log* GetInstance(){static Log oLog;return &oLog;}void Output(string strLog){cout<<strLog<<(*m_pInt)<<endl;}
private:Log():m_pInt(new int(3)){}~Log(){cout<<"~Log"<<endl;delete m_pInt;m_pInt = NULL;}int* m_pInt;
};class Context
{
public:static Context* GetInstance(){static Context oContext;return &oContext;}~Context(){Log::GetInstance()->Output(__FUNCTION__);}void fun(){Log::GetInstance()->Output(__FUNCTION__);}
private:Context(){}Context(const Context& context);
};int main(int argc, char* argv[])
{Context::GetInstance()->fun();return 0;
}

參考博客:https://www.freesion.com/article/7937607333/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/447126.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/447126.shtml
英文地址,請注明出處:http://en.pswp.cn/news/447126.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

區塊鏈中密碼學與安全技術

區塊鏈的定義 區塊鏈的定義&#xff0c;應當是&#xff1a;區塊鏈是一種按照時間順序將數據進行分布式存儲的塊鏈式數據結構&#xff0c;它利用共識機制進行數據驗證&#xff0c;利用密碼學進行數據保護和用戶安全訪問&#xff0c;利用智能合約來操作數據&#xff0c;從而成為…

面經:服務器相關

阻塞IO 當你去讀一個阻塞的文件描述符時&#xff0c;如果在該文件描述符上沒有數據可讀&#xff0c;那么它會一直阻塞(通俗一點就是一直卡在調用函數那里)&#xff0c;直到有數據可讀。當你去寫一個阻塞的文件描述符時&#xff0c;如果在該文件描述符上沒有空間(通常是緩沖區)…

如何用區塊鏈保障數據安全和承載數據確權

區塊鏈可以確保數據安全&#xff0c;體現在那些方面呢&#xff1f; 主要是兩個維度&#xff0c;一是數據的不可篡改性&#xff1b;另外一個就是數據的隱私安全性。區塊鏈技術本身并不解決任何的安全問題&#xff0c;因此需要搭配安全技術一起使用&#xff0c;比如非對稱加密、…

面經:單例模式

侯捷單例 和劍指不同 &#xfffc; 餓漢式 餓漢式的特點是一開始就加載了&#xff0c;如果說懶漢式是“時間換空間”&#xff0c;那么餓漢式就是“空間換時間”&#xff0c;因為一開始就創建了實例&#xff0c;所以每次用到的之后直接返回就好了。餓漢式有兩種常見的寫法&…

屬性加密技術及基于屬性的ABE算法的訪問控制技術介紹

屬性加密技術 基于身份的加密體制簡介 基于身份的加密體制可以看作一種特殊的公鑰加密&#xff0c;它有如下特點:系統中用戶的公鑰可以由任意的字符串組成。這些字符串可以是用戶在現實中的身份信息&#xff0c;如:身份證號碼、用戶姓名、電話號碼、Email地址等&#xff0c;因…

面經:http協議

總結HTTPS傳輸過程 客戶端先從服務器獲取到證書&#xff0c;證書中包含公鑰 客戶端將證書進行校驗 客戶端生成一個對稱密鑰&#xff0c;用證書中的公鑰進行加密&#xff0c;發送給服務器 服務器得到這個請求后用私鑰進行解密&#xff0c;得到該密鑰 客戶端以后發出后續的請求&…

基于屬性加密的ABE算法的應用場景思考展望

ABE算法先前使用在云計算場景中&#xff0c;和區塊鏈存在交叉應用場景&#xff0c;具體問題體現在 數據的異地存儲、云服務器提供商的不可信、管理員能否對自身數據擁有足夠的控制能力以及如何保證數據的安全有效共享都是亟需解決的問題。 研究背景&#xff1a; 云計算越來越…

面經:設計模式

什么是接口隔離原則&#xff08;Interface Segregation Principle&#xff09; 定義&#xff1a;客戶端不應該依賴它不需要的接口&#xff1b;一個類對另一個類的依賴應該建立在最小的接口上。概括的說就是&#xff1a;建立單一接口&#xff0c;不要建立臃腫龐大的接口。&…

區塊鏈、密碼和銀行之間的衍生關系

銀行場景中密碼服務 設置密碼 用戶在注冊的時候&#xff0c;如果使用弱密碼&#xff0c;系統會檢測出來。我的猜測是將弱密碼的hash運算和用戶輸入的密碼hash比對&#xff0c;如果一致&#xff0c;禁止用戶注冊。 1、不要設置簡單密碼&#xff0c;您設置的密碼必須符合中信銀…

面經:多線程 線程池

使用線程池 當進程被初始化后&#xff0c;主線程就被創建了。對于絕大多數的應用程序來說&#xff0c;通常僅要求有一個主線程&#xff0c;但也可以在進程內創建多個順序執行流&#xff0c;這些順序執行流就是線程&#xff0c;每一個線程都是獨立的。 線程是進程的組成部分&am…

AIgorand區塊鏈中VRF隨機函數的應用

VRF&#xff08;Verifiable Random Function&#xff09; 可驗證隨機函數可以看作是一個隨機預言機&#xff0c;即可以通過任意的一個輸入&#xff0c;獲得一個隨機數輸出&#xff1a;輸出的結果&#xff08;Output&#xff09;是一個隨機數&#xff0c;其數值會均勻分布在值域…

AIgorand的相關學習參考鏈接

相關具體的開發者與SDK鏈接如下&#xff1a; GoSDKJavaScript SDK 網頁鏈接 測試網申請鏈接Github存儲庫鏈接開發者網址AIgorand官網Telegram電報群綜合白皮書MediumNaver Blog領英Linkedin區塊鏈瀏覽器INC公示錢包地址基金會公示錢包地址Telegram電報群官方 Github地址 相關…

操作系統 內核棧

視頻哈工大李治軍老師&#xff1a;https://www.bilibili.com/video/BV1d4411v7u7?p12 參考文檔&#xff1a;https://blog.csdn.net/SakuraA6/article/details/108810916 學長在我大一推薦我看&#xff0c;p12和p13的內容真的有那么難嗎&#xff0c;現在已經是我看的第三遍了還…

區塊鏈技術指南 序章理解感悟

序二 誤區一&#xff1a; 區塊鏈是一種顛覆性的新技術。區塊鏈不是一個新的技術&#xff0c;而是一個新的技術的組合。其關鍵的技術&#xff0c;包括P2P動態組網、基于密碼學的共享賬本、共識機制&#xff08;拜占庭將軍問題&#xff0c;分布式場景下的一致性問題&#xff09…

面經:紅黑樹 B樹 B+樹 哈希表

1.對于插入&#xff0c;刪除&#xff0c;查找 以及 輸出有序序列 這幾個操作&#xff0c;紅黑樹也可以完成&#xff0c;時間復雜度 與 用跳表實現是相同的。 但是&#xff0c;對于按照區間查找數據這個操作&#xff08;比如 [20,300]&#xff09;,紅黑樹的效率沒有跳表高&#…

回溯法和dfs的區別

值得注意&#xff0c;回溯法以深度優先搜索的方式搜索解空間&#xff0c;并且在搜索過程中用剪枝函數避免無效搜索。那為何 回溯算法 深度優先搜索 剪枝函數這一說法沒有錯&#xff1f; 因為樹是特殊的圖。簡單來說&#xff0c;樹是廣義的圖。再簡單來說&#xff0c;樹是圖。…

C++學習筆記 簡單部分

C 數據類型 使用變量來存儲各種信息&#xff0c;變量保留的是它所存儲的值的內存位置。這意味著&#xff0c;當創建一個變量時&#xff0c;就會在內存中保留一些空間。這段內存空間可以用于存儲各種數據類型&#xff08;比如字符型、寬字符型、整型、浮點型、雙浮點型、布爾型…

Redis kqeue相關源碼

mask 或delmask &#xff1a;添加或者刪除的事件類型&#xff0c;AE_NONE表示沒有任何事件&#xff1b;AE_READABLE表示可讀事件&#xff1b;AE_WRITABLE表示可寫事件&#xff1b; 如aeCreateFileEvent(loop,e->fd,AE_READABLE,redisAeReadEvent,e); static int aeApiAddEv…

C++學習筆記章節中 面向對象詳解

C 類&對象 C類定義 本質上是一個數據類型的藍圖&#xff0c;定義了類的對象包含的信息&#xff0c;以及可以在這個類對象上執行哪些操作。類的定義是以class開頭&#xff0c;后面接類的名稱。類的主體是包含在一個花括號中&#xff0c;類的定義之后&#xff0c;必須跟著一…

Mac 破解軟件打不開沒有權限

Mac 破解軟件打不開沒有權限 sudo codesign -fs - /Applications/CleanMyMac\ X.app文件損壞 xxx sudo xattr -r -d /Applications/MarginNote\ 3.app sudo xattr -r -d com.apple.quarantine xxxx sudo codesign --force --deep --sign - /Applications/MarginNote\ 3\…