<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Qt小知識2.Q_GLOBAL_STATIC

      1 了解Q_GLOBAL_STATIC

      Q_GLOBAL_STATIC 是 Qt 中提供的一個宏,用于創建跨越多個文件的全局靜態對象。其主要作用在于兩點:

      1. 懶惰初始化(Lazy initialization):它確保全局靜態對象只有在首次使用時才被創建,而不是在程序啟動時立即創建,從而可以減少程序啟動時的初始化開銷。
      2. 線程安全(Thread safety):在多線程環境中,Q_GLOBAL_STATIC 保證了全局靜態對象的初始化是線程安全的,即使多個線程試圖同時第一次訪問它,對象也只會被創建一次。

      2 實際應用

      下面是一個使用 Q_GLOBAL_STATIC 的示例:

      #include <QMutex>
      #include <QDebug>
      #include <QCoreApplication>
      
      // 定義一個全局的互斥鎖,用于跨線程同步訪問
      struct GlobalMutex {
          QMutex mutex;
      };
      
      Q_GLOBAL_STATIC(GlobalMutex, globalMutex)
      
      int main(int argc, char *argv[]) {
          QCoreApplication a(argc, argv);
      
          // 當需要使用這個全局互斥鎖時
          globalMutex()->mutex.lock();
          qDebug() << "Doing some thread-safe operation...";
          globalMutex()->mutex.unlock();
      
          return a.exec();
      }
      

      在這個例子中,定義了一個 GlobalMutex 結構體,包含一個 QMutex 對象。然后使用 Q_GLOBAL_STATIC 宏來創建一個全局靜態的 GlobalMutex 實例,命名為 globalMutex。這個互斥鎖可以在程序的任何地方使用,并保證只在首次使用時被初始化,同時保證了其初始化過程是線程安全的。

      引用全局靜態對象使用 globalMutex() 函數調用的方式(注意是一個函數調用語法),這是 Q_GLOBAL_STATIC 語法的特征,可以保證按需創建(懶惰初始化)并且是線程安全的。

      使用 Q_GLOBAL_STATIC 的好處是它避免了程序中手動管理全局變量初始化順序的復雜度,也消除了"SIOF - Static Initialization Order Fiasco"(靜態初始化順序問題)的風險,因為靜態對象僅在首次訪問時被創建,避免了因依賴其他全局對象在初始化時還未創建導致的問題。同時,當全局對象具有復雜的構造和析構過程時,使用 Q_GLOBAL_STATIC 可以確保安全地創建和清理資源。

      “SIOF - Static Initialization Order Fiasco”(靜態初始化順序問題)指的是在C++程序中,不同編譯單元(通常是不同的源文件)中全局(或靜態)對象的初始化順序是未定義的。
      也就是說,如果有兩個全局靜態對象,一個位于文件A中,另一個位于文件B中,且對象A在其初始化過程中依賴對象B,那么就存在一個問題:在主函數 main() 開始執行之前,無法保證對象B一定在對象A之前被初始化。如果對象A在它的構造函數中訪問了對象B,而對象B還沒有被初始化,這可能會導致未定義的行為,比如訪問無效的內存,導致程序崩潰等問題。
      Q_GLOBAL_STATIC 通過懶加載模式解決了這個問題。當首次使用全局對象時,這個對象才會被創建,并且這個創建過程是線程安全的。這意味著無論全局對象的定義在哪個編譯單元中,它們都將在實際使用時才被初始化,而不是在程序啟動時。
      這樣一來,就消除了因為靜態初始化順序引起的未定義行為。任何一個全局對象在實際被使用前都不會被初始化,因此,它們的初始化過程可以安全地引用其他全局對象,不會由于它們尚未初始化而出錯。只要對象的使用順序正確,它們的依賴關系就可以正常工作,因為實際使用時所依賴的對象已經被創建了。

      Q_GLOBAL_STATIC 也經常用于需要在整個應用程序中訪問的單例對象,例如日志工具、應用程序配置或者性能監控器等。以下是一個使用 Q_GLOBAL_STATIC 宏來創建和使用應用程序配置單例的例子:

      #include <QString>
      #include <QCoreApplication>
      
      // 假設這是應用程序配置類
      class AppConfig {
      public:
          AppConfig() {
              // 加載或初始化配置
          }
      
          QString getValue(const QString &key) {
              // 假設從某處獲取配置值
              return "Some Config Value";
          }
      };
      
      Q_GLOBAL_STATIC(AppConfig, appConfigInstance)
      
      int main(int argc, char *argv[]) {
          QCoreApplication app(argc, argv);
      
          // 使用全局配置實例
          QString configValue = appConfigInstance()->getValue("someKey");
          // Do something with configValue
      
          return app.exec();
      }
      

      在這個例子中,AppConfig 類代表一個配置管理器,它負責加載、保存和獲取應用程序配置。通過 Q_GLOBAL_STATIC 宏聲明了一個 AppConfig 的全局靜態實例 appConfigInstance。

      然后,在 main 函數中,通過 appConfigInstance() 函數調用來訪問這個全局配置實例,并從中獲取配置值。和前例一樣,這種訪問方式保證了 AppConfig 的實例只有在首次使用時才創建,從而實現懶惰初始化,并且是線程安全的。

      這樣的做法特別適用于配置管理的場景,因為往往需要在應用程序的多個位置訪問和修改配置,而不希望每次都創建配置類的實例,Q_GLOBAL_STATIC 提供了一種方便的全局訪問點。

      3 了解Q_GLOBAL_STATIC_WITH_ARGS

      Q_GLOBAL_STATIC_WITH_ARGS 是 Q_GLOBAL_STATIC 的一個變體,它允許使用參數來初始化全局靜態對象。這意味著當全局靜態對象需要在構造函數中傳遞一些參數來初始化時,Q_GLOBAL_STATIC_WITH_ARGS 就特別有用。

      其語法與 Q_GLOBAL_STATIC 相似,但是它允許在宏的第二個參數中傳入一個構造函數參數列表。

      下面是使用 Q_GLOBAL_STATIC_WITH_ARGS 的一個示例:

      #include <QString>
      #include <QCoreApplication>
      
      // 假設這是一個需要參數初始化的類
      class Logger {
      public:
          Logger(QString logFileName) {
              // 假設使用這個文件名初始化日志系統
              _logFileName = logFileName;
          }
      
          void log(const QString &message) {
              // 假設記錄日志到文件
          }
      
      private:
          QString _logFileName;
      };
      
      // 使用指定的日志文件名初始化全局日志對象
      Q_GLOBAL_STATIC_WITH_ARGS(Logger, globalLogger, (QString("application.log")))
      
      int main(int argc, char *argv[]) {
          QCoreApplication app(argc, argv);
      
          // 使用全局日志對象記錄一條消息
          globalLogger()->log("Application started");
      
          return app.exec();
      }
      

      在這個例子中,Logger 類是一個日志記錄器,它通過構造函數接收一個日志文件名來初始化。使用 Q_GLOBAL_STATIC_WITH_ARGS 宏創建了一個全局的 Logger 實例 globalLogger,并通過傳遞了一個參數 "application.log" 作為日志文件名進行初始化。

      然后,在 main 函數中,使用 globalLogger() 來獲取全局日志實例并記錄一條消息,這與前面的 Q_GLOBAL_STATIC 示例類似。全局的 Logger 實例會在首次使用時進行懶惰初始化,并保證初始化的線程安全性。

      通過這種方式,Q_GLOBAL_STATIC_WITH_ARGS 引入了構造函數參數,提供了更多的靈活性,用于初始化那些需要額外信息才能正確創建的全局靜態對象。

      4 總結

      Q_GLOBAL_STATIC 提供了一個安全的模式來創建、使用和清理全局對象,這在大型應用程序中特別有用。它簡化了單例模式的使用,并且避免了手動管理全局資源帶來的復雜性和風險。

      posted @ 2023-12-13 14:20  Qt小羅  閱讀(1789)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产AV影片麻豆精品传媒| 亚洲人成电影网站色mp4| 亚洲一区二区三区四区| 日韩中文字幕亚洲精品| 高清无码在线视频| 亚洲嫩模喷白浆在线观看| 国产一区二区丰满熟女人妻| 丝袜高潮流白浆潮喷在线播放| 熟妇人妻不卡中文字幕| 久久亚洲精品成人av秋霞| 国产成人亚洲一区二区三区| h动态图男女啪啪27报gif| 亚洲免费成人av一区| 日韩精品av一区二区三区| 成人亚欧欧美激情在线观看| 在线中文字幕国产精品| 东京热无码国产精品| 久久久久无码精品国产AV| 汶上县| 在线国产精品中文字幕| 自拍偷自拍亚洲精品情侣| 无码视频伊人| 亚洲狠狠婷婷综合久久久| 自拍偷自拍亚洲精品熟妇人| 99久久精品免费看国产电影| 日本一区不卡高清更新二区 | 国产无遮挡性视频免费看| 国产熟女肥臀精品国产馆乱| 亚洲国产亚洲综合在线尤物| 日本一卡2卡3卡四卡精品网站| 久久综合国产一区二区三区| 日日噜噜夜夜狠狠视频| 她也色tayese在线视频| 国产一区二区高清不卡| 国产一区二区三区禁18| 不卡一区二区三区四区视频| 日本欧美大码a在线观看| 任我爽精品视频在线播放| 色综合久久天天综线观看| 国产成人精品一区二区三区 | 永久免费精品性爱网站|