c++中單例模式使用及說(shuō)明(局部靜態(tài)變量)
單例模式的作用
單例模式的核心在于確保一個(gè)類只有一個(gè)實(shí)例,并為整個(gè)系統(tǒng)提供統(tǒng)一的訪問(wèn)入口,從而實(shí)現(xiàn)資源與邏輯的精簡(jiǎn)。
它通過(guò)私有化構(gòu)造函數(shù)來(lái)禁止外部隨意創(chuàng)建對(duì)象,強(qiáng)制所有代碼通過(guò)同一個(gè)靜態(tài)方法獲取唯一實(shí)例。
這樣做既避免了重復(fù)創(chuàng)建重量級(jí)對(duì)象(如配置管理器、數(shù)據(jù)庫(kù)連接池)的資源浪費(fèi),也簡(jiǎn)化了對(duì)象在系統(tǒng)各處的傳遞與訪問(wèn)——你不需要在多個(gè)模塊間手動(dòng)傳遞同一個(gè)對(duì)象,只需通過(guò)全局訪問(wèn)點(diǎn)直接獲取即可。
這種設(shè)計(jì)將對(duì)象的生命周期與訪問(wèn)方式標(biāo)準(zhǔn)化,讓代碼更聚焦于業(yè)務(wù)邏輯而非對(duì)象管理。但需警惕,過(guò)度使用單例會(huì)引入全局狀態(tài)隱式耦合,增加測(cè)試復(fù)雜度,因此應(yīng)嚴(yán)格限定于真正需要“唯一性”的場(chǎng)景。
總結(jié):
- 單例模式通過(guò)控制實(shí)例數(shù)量和提供統(tǒng)一訪問(wèn)點(diǎn),實(shí)現(xiàn)資源管理的精簡(jiǎn)與代碼結(jié)構(gòu)的簡(jiǎn)化。
- 但需注意多線程安全、單元測(cè)試難度等潛在問(wèn)題,避免濫用。
單例模式(局部靜態(tài)變量模式)
//靜態(tài)局部變量方式實(shí)現(xiàn)單例模式
#include<iostream>
using namespace std;
class S {
private:
S() {}
S(const S&) = delete;
S& operator=(const S&) = delete;
public:
static S& getS() {
static S s;
return s;
}
};
單例模式的應(yīng)用(局部靜態(tài)變量)
#include <iostream>
#include <string>
#include <unordered_map>
/**
* 配置管理器單例類
* 在大型項(xiàng)目中,通常需要一個(gè)全局唯一的配置中心來(lái)管理各種服務(wù)配置項(xiàng)
* 如數(shù)據(jù)庫(kù)連接信息、API密鑰、服務(wù)器端口等
*/
class ConfigManager {
private:
// 私有構(gòu)造函數(shù),防止外部直接創(chuàng)建實(shí)例
ConfigManager() {
// 在構(gòu)造函數(shù)中加載默認(rèn)配置
loadDefaultConfig();
std::cout << "ConfigManager 初始化完成,加載默認(rèn)配置" << std::endl;
}
// 刪除拷貝構(gòu)造函數(shù)和賦值操作符,確保單例的唯一性
ConfigManager(const ConfigManager&) = delete;
ConfigManager& operator=(const ConfigManager&) = delete;
// 加載默認(rèn)配置的方法
void loadDefaultConfig() {
configMap["database_host"] = "localhost";
configMap["database_port"] = "3306";
configMap["redis_host"] = "localhost";
configMap["redis_port"] = "6379";
configMap["api_timeout"] = "5000"; // 毫秒
configMap["max_connections"] = "100";
}
// 存儲(chǔ)配置項(xiàng)的哈希表
std::unordered_map<std::string, std::string> configMap;
public:
/**
* 獲取單例實(shí)例的靜態(tài)方法
* C++11 標(biāo)準(zhǔn)保證 static 局部變量的初始化是線程安全的
*/
static ConfigManager& getInstance() {
static ConfigManager instance; // 靜態(tài)局部變量,延遲初始化
return instance;
}
/**
* 獲取配置值
* @param key 配置項(xiàng)鍵名
* @return 配置項(xiàng)對(duì)應(yīng)的值,如果不存在則返回空字符串
*/
std::string getConfig(const std::string& key) const {
auto it = configMap.find(key);
//std::map<KeyType, ValueType>::iterator it = configMap.find(key);//傳統(tǒng)寫法
if (it != configMap.end()) {
return it->second;
}
std::cout << "警告: 未找到配置項(xiàng) '" << key << "'" << std::endl;
return "";
}
/**
* 設(shè)置配置值
* 在實(shí)際項(xiàng)目中,這個(gè)方法可能用于動(dòng)態(tài)更新配置
* @param key 配置項(xiàng)鍵名
* @param value 配置項(xiàng)值
*/
void setConfig(const std::string& key, const std::string& value) {
configMap[key] = value;
std::cout << "配置項(xiàng) '" << key << "' 更新為: " << value << std::endl;
}
/**
* 打印所有配置項(xiàng)(用于調(diào)試)
*/
void printAllConfigs() const {
std::cout << "\n=== 當(dāng)前所有配置 ===" << std::endl;
for (const auto& pair : configMap) {
std::cout << pair.first << " = " << pair.second << std::endl;
}
std::cout << "==================\n" << std::endl;
}
};
/**
* 模擬數(shù)據(jù)庫(kù)連接類
* 使用配置管理器獲取數(shù)據(jù)庫(kù)連接參數(shù)
*/
class DatabaseConnection {
public:
DatabaseConnection() {
// 從配置管理器獲取數(shù)據(jù)庫(kù)連接參數(shù)
auto& config = ConfigManager::getInstance();
host = config.getConfig("database_host");
port = config.getConfig("database_port");
std::cout << "正在連接數(shù)據(jù)庫(kù): " << host << ":" << port << std::endl;
}
private:
std::string host;
std::string port;
};
/**
* 模擬 Redis 連接類
* 同樣使用配置管理器獲取 Redis 連接參數(shù)
*/
class RedisConnection {
public:
RedisConnection() {
// 從配置管理器獲取 Redis 連接參數(shù)
auto& config = ConfigManager::getInstance();
host = config.getConfig("redis_host");
port = config.getConfig("redis_port");
std::cout << "正在連接 Redis: " << host << ":" << port << std::endl;
}
private:
std::string host;
std::string port;
};
int main() {
std::cout << "=== 大廠項(xiàng)目配置管理器演示 ===" << std::endl;
// 場(chǎng)景1: 數(shù)據(jù)庫(kù)連接器獲取配置
std::cout << "\n--- 初始化數(shù)據(jù)庫(kù)連接 ---" << std::endl;
DatabaseConnection dbConn;
// 場(chǎng)景2: Redis連接器獲取配置
std::cout << "\n--- 初始化Redis連接 ---" << std::endl;
RedisConnection redisConn;
// 場(chǎng)景3: 驗(yàn)證單例的唯一性
std::cout << "\n--- 驗(yàn)證單例模式 ---" << std::endl;
auto& config1 = ConfigManager::getInstance();
auto& config2 = ConfigManager::getInstance();
if (&config1 == &config2) {
std::cout << "驗(yàn)證成功: 兩次獲取的實(shí)例是同一個(gè)對(duì)象" << std::endl;
}
else {
std::cout << "驗(yàn)證失敗: 獲取到了不同的實(shí)例" << std::endl;
}
// 場(chǎng)景4: 動(dòng)態(tài)修改配置
std::cout << "\n--- 動(dòng)態(tài)修改配置 ---" << std::endl;
auto& config = ConfigManager::getInstance();
config.setConfig("database_host", "prod-database.company.com");
config.setConfig("api_timeout", "10000");
// 驗(yàn)證配置是否更新
std::cout << "更新后的數(shù)據(jù)庫(kù)主機(jī): " << config.getConfig("database_host") << std::endl;
std::cout << "更新后的API超時(shí)時(shí)間: " << config.getConfig("api_timeout") << "ms" << std::endl;
// 場(chǎng)景5: 打印所有配置
config.printAllConfigs();
// 場(chǎng)景6: 模擬新連接使用更新后的配置
std::cout << "\n--- 新連接使用更新后的配置 ---" << std::endl;
DatabaseConnection newDbConn; // 這個(gè)連接會(huì)使用更新后的主機(jī)地址
return 0;
}
運(yùn)行結(jié)果

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)紙牌游戲(小貓釣魚)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)紙牌游戲,小貓釣魚游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10
C語(yǔ)言實(shí)現(xiàn)登錄注冊(cè)和忘記密碼功能
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)登錄、注冊(cè)和忘記密碼功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
C語(yǔ)言實(shí)現(xiàn)時(shí)間處理工具的示例代碼
這篇文章主要為大家詳細(xì)介紹了利用C語(yǔ)言實(shí)現(xiàn)時(shí)間處理工具的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下2022-09-09
C++中vector的模擬實(shí)現(xiàn)實(shí)例詳解
vector是表示可變大小數(shù)組的序列容器,它也采用連續(xù)存儲(chǔ)空間來(lái)存儲(chǔ)元素,因此可以采用下標(biāo)對(duì)vector的元素進(jìn)行訪問(wèn),這篇文章主要給大家介紹了關(guān)于C++中vector模擬實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2021-11-11
Qt操作SQLite數(shù)據(jù)庫(kù)的教程詳解
SQLite是一款開源、輕量級(jí)、跨平臺(tái)的數(shù)據(jù)庫(kù),無(wú)需server,無(wú)需安裝和管理配置。它的設(shè)計(jì)目標(biāo)是嵌入式的,所以很適合小型應(yīng)用,也是Qt應(yīng)用開發(fā)種常用的一種數(shù)據(jù)庫(kù)。本文為大家介紹了Qt操作SQLite數(shù)據(jù)庫(kù)的示例,希望對(duì)大家有所幫助2022-12-12
C++從匯編的視角審視對(duì)象的創(chuàng)建問(wèn)題
這篇文章主要介紹了C++從匯編的視角看對(duì)象的創(chuàng)建,從匯編的視角來(lái)看,調(diào)用構(gòu)造器和調(diào)用 “返回對(duì)象” 的函數(shù)是一樣的,從匯編的角度來(lái)看,對(duì)象就是一堆數(shù)據(jù)的排列,比如說(shuō)最普通的對(duì)象就是數(shù)據(jù)成員按照聲明順序直接排列,需要的朋友可以參考下2022-01-01

