日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++静态类型成员变量的初始化顺序(单例模式)

發布時間:2023/12/13 c/c++ 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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函數會逐個調?這些析構函數,完成進程結束前的掃尾?作?;诖?#xff0c;很顯然,對于分布在程序各處的靜態局部變
量,其構造順序取決于它們在程序的實際執?路徑上的先后順序,?析構順序則正好與之相反。
很簡單,不是么?可為什么說是隱藏的坑呢,問題在于:

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

既然提出問題,那么就討論應對之道:
(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/

總結

以上是生活随笔為你收集整理的C++静态类型成员变量的初始化顺序(单例模式)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。