C++實現單例模式日志輸出詳解

一、單例模式簡單介紹

1.1 基礎介紹

單例模式隻保證一個程序內隻有一個實例存在,並提供全局訪問點來訪問該實例,其實就是單例模式的類對象隻允許存在一個,它和多線程思想恰恰相反,為的是保證操作資源的安全。比如日志系統需要記載時間的,如果多線程會搞得很亂。

實現單例模式的關鍵是構造函數需要被設為私有,以防止外部代碼創建多個實例。同時,需要提供一個靜態方法來獲取實例,這個方法會檢查是否已經有一個實例存在,如果存在就返回這個實例,否則就創建一個新的實例並返回。

下面是一個簡單的 C++ 單例模式示例代碼:

class Singleton {
public:
  static Singleton* GetInstance() {
    if (instance_ == nullptr) {
      instance_ = new Singleton();
    }
    return instance_;
  }
 
  void DoSomething() {
    // ...
  }
 
private:
  Singleton() {
    // ...
  }
 
  static Singleton* instance_;
};
 
Singleton* Singleton::instance_ = nullptr;

1.2 單例模式使用場景

1.配置管理器:在一個應用程序中,配置信息可能需要在多個地方被訪問,而且這些配置信息通常是隻讀的。使用單例模式可以保證配置信息隻被加載一次,同時提供一個全局訪問點來訪問配置信息。

2.日志記錄器:在一個應用程序中,日志信息可能需要在多個地方被記錄,而且記錄器通常是隻有一個的。使用單例模式可以保證隻有一個日志記錄器被創建,並且提供一個全局訪問點來記錄日志信息。

3.數據庫連接池:在一個應用程序中,需要連接數據庫的地方可能很多,而且數據庫連接通常是有限的資源。使用單例模式可以實現數據庫連接池,保證連接隻被創建一次,並且提供一個全局訪問點來獲取連接。

4.計數器:在一個應用程序中,可能需要對某個事件或操作進行計數統計,而且這些計數器通常是隻有一個的。使用單例模式可以保證計數器隻被創建一次,並且提供一個全局訪問點來進行計數。

5.緩存管理器:在一個應用程序中,需要對某些數據進行緩存,而且緩存數據的容量通常是有限的。使用單例模式可以實現緩存管理器,保證緩存隻被創建一次,並且提供一個全局訪問點來訪問緩存數據。

二、單例模式實現日志記錄(Singleton Logger)

#include <iostream>
#include <fstream>
#include <string>
#include <ctime>
 
using namespace std;
 
class Logger {
private:
    static Logger* instance;
    ofstream logFile;
 
    Logger() {
        string filename = "log.txt";
        logFile.open(filename.c_str(), ios::out | ios::app);
    }
 
public:
    static Logger* getInstance() {
        if (instance == NULL) {
            instance = new Logger();
        }
        return instance;
    }
 
    void log(string message) {
        time_t now = time(0);
        char* dt = ctime(&now);
        logFile << dt << ": " << message << endl;
    }
};
 
Logger* Logger::instance = NULL;
 
int main() {
    Logger* logger = Logger::getInstance();
    logger->log("Hello World!");
    return 0;
}

在上述代碼中,Logger類具有私有的構造函數和一個私有的靜態成員變量instance。getInstance()函數是一個公有的靜態成員函數,它返回Logger類的唯一實例。如果實例不存在,則創建一個新的實例。log()函數用於向日志文件寫入消息。

在main函數中,我們首先獲取Logger實例,然後調用log()函數記錄日志。由於Logger類是單例模式,因此在程序運行期間隻會有一個Logger實例存在,因此多次調用log()函數將在同一個文件中記錄日志。

請註意,由於單例模式在多線程環境下可能存在問題,因此需要進行線程安全的處理。在本例中,我們忽略瞭線程安全問題,僅提供瞭單線程環境下的實現。

三、總結

單例模式很辛苦,很孤單,請善待單例模式。

到此這篇關於C++實現單例模式日志輸出詳解的文章就介紹到這瞭,更多相關C++單例模式內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: