JsonCPP源碼分析——分配器和配置器

1、allocator.h文件
該文件定義了一個分配器模版,該文件主要使用了內存對齊控制、rebind機制(C++ 標準庫的分配器接口要求提供 rebind 機制,以支持不同類型的分配)、::operator new、std::addressof等技術。

  • 內存對齊控制:之所以先保存當前內存對齊方式,最后再恢復,是想把json對象的內存對齊方式和使用它的對象的內存方式隔離開
#pragma pack(push)  //保存當前內存對齊方式
#pragma pack() // 使用編譯器默認內存對齊方式... // 使用默認內存對齊方式的代碼
#pragma pack(pop) // 恢復之前的內存對齊方式
  • rebind機制: C++ 標準庫的分配器接口要求提供 rebind 機制,以支持不同類型的分配,rebind 機制可以理解為允許分配器為不同類型的對象分配內存空間。這種機制使得標準庫容器能夠使用相同的分配器實例來分配其所有元素類型的內存。rebind 機制允許你通過一個分配器類型生成另一個類型的分配器。例如,如果你有一個 SecureAllocator,你可以通過 rebind 機制得到一個SecureAllocator,從而使用相同的分配器為 double 類型的對象分配內存。使用方式如下:
SecureAllocator<int> intAlloc;
SecureAllocator<int>::rebind<double>::other doubleAlloc;
  • ::operator new: 只分配空間而不調用構造函數,如果直接new,既分配空間又調用構造函數。前者需要程序員控制調用構造函數,析構函數,銷毀空間,后者直接delete或delete []即可。
  • std::addressof是C++11新引入的,它的主要作用是獲取對象的地址,這樣的優點是放在類對&進行重寫而改變了取地址的含義。
#ifndef JSON_ALLOCATOR_H_INCLUDED
#define JSON_ALLOCATOR_H_INCLUDED#include <cstring>
#include <memory>
/*
預處理命令#pragma pack(push)用來保存當前的內存對齊方式
#pragma pack()用來使用編譯器默認的內存對齊方式
*/
#pragma pack(push)
#pragma pack()namespace Json {
template <typename T> class SecureAllocator {
public:// 類型定義using value_type = T;using pointer = T*;using const_pointer = const T*;using reference = T&;using const_reference = const T&;using size_type = std::size_t;using difference_type = std::ptrdiff_t;// 默認構造函數SecureAllocator() {}// 拷貝構造函數模板template <typename U> SecureAllocator(const SecureAllocator<U>&) {}// rebind 結構體模板template <typename U> struct rebind { using other = SecureAllocator<U>; };// 分配內存pointer allocate(size_type n) {return static_cast<pointer>(::operator new(n * sizeof(T)));}// 釋放內存void deallocate(pointer p, size_type n) {memset_s(p, n * sizeof(T), 0, n * sizeof(T));::operator delete(p);}// 在已分配內存上構造對象,就地構造template <typename... Args> void construct(pointer p, Args&&... args) {::new (static_cast<void*>(p)) T(std::forward<Args>(args)...);}// 獲取對象的地址pointer address(reference x) const { return std::addressof(x); }const_pointer address(const_reference x) const { return std::addressof(x); }// 獲取最大可分配數量size_type max_size() const { return size_t(-1) / sizeof(T); }// 在已分配內存上銷毀對象void destroy(pointer p) {p->~T();}
};// 比較操作符
template <typename T, typename U>
bool operator==(const SecureAllocator<T>&, const SecureAllocator<U>&) {return true;
}template <typename T, typename U>
bool operator!=(const SecureAllocator<T>&, const SecureAllocator<U>&) {return false;
}
} // namespace Json//恢復原有的內存對齊方式
#pragma pack(pop)#endif // JSON_ALLOCATOR_H_INCLUDED

2、config.h文件

  • 動態庫導入導出符號在不同的平臺和編譯器中的處理方式不一樣,需要對導出的符號進行特定的處理,以確保正確導出和導入。JSON_DLL_BUILD:在編譯動態庫時定義。用于標識正在編譯動態庫。JSON_DLL:在使用動態庫時定義。用于標識正在使用動態庫。JSON_API:根據不同的編譯器和平臺,定義導出和導入符號的宏。可以理解為在編譯動態庫和使用動態庫時,JSON_API的值是不一樣的。
// Export macros for DLL visibility
#if defined(JSON_DLL_BUILD)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllexport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#elif defined(__GNUC__) || defined(__clang__)
#define JSON_API __attribute__((visibility("default")))
#endif // if defined(_MSC_VER)#elif defined(JSON_DLL)
#if defined(_MSC_VER) || defined(__MINGW32__)
#define JSON_API __declspec(dllimport)
#define JSONCPP_DISABLE_DLL_INTERFACE_WARNING
#endif // if defined(_MSC_VER)
#endif // ifdef JSON_DLL_BUILD#if !defined(JSON_API)
#define JSON_API
#endif
  • MSVC版本兼容性
#if defined(_MSC_VER) && _MSC_VER < 1800
#error                                                                         \"ERROR:  Visual Studio 12 (2013) with _MSC_VER=1800 is the oldest supported compiler with sufficient C++11 capabilities"
#endif#if defined(_MSC_VER) && _MSC_VER < 1900
// As recommended at
// https://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010
extern JSON_API int msvc_pre1900_c99_snprintf(char* outBuf, size_t size,const char* format, ...);
#define jsoncpp_snprintf msvc_pre1900_c99_snprintf
#else
#define jsoncpp_snprintf std::snprintf
#endif
  • 根據編譯器版本設置棄用宏JSONCPP_DEPRECATED,它可以向編譯器表明某個函數或變量已被棄用,并提供一個棄用消息。
#ifdef __clang__
#if __has_extension(attribute_deprecated_with_message)
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
#endif
#elif defined(__GNUC__) // not clang (gcc comes later since clang emulates gcc)
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5))
#define JSONCPP_DEPRECATED(message) __attribute__((deprecated(message)))
#elif (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
#define JSONCPP_DEPRECATED(message) __attribute__((__deprecated__))
#endif                  // GNUC version
#elif defined(_MSC_VER) // MSVC (after clang because clang on Windows emulates// MSVC)
#define JSONCPP_DEPRECATED(message) __declspec(deprecated(message))
#endif // __clang__ || __GNUC__ || _MSC_VER#if !defined(JSONCPP_DEPRECATED)
#define JSONCPP_DEPRECATED(message)
#endif // if !defined(JSONCPP_DEPRECATED)#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 6))
#define JSON_USE_INT64_DOUBLE_CONVERSION 1
#endif
  • 類型定義,std::conditional:根據條件選擇不同的類型,std::basic_string:使用自定義分配器的字符串類型,std::basic_istringstream 和 std::basic_ostringstream:使用自定義分配器的字符串輸入輸出流
namespace Json {
using Int = int;
using UInt = unsigned int;
#if defined(JSON_NO_INT64)
using LargestInt = int;
using LargestUInt = unsigned int;
#undef JSON_HAS_INT64
#else
#if defined(_MSC_VER)
using Int64 = __int64;
using UInt64 = unsigned __int64;
#else
using Int64 = int64_t;
using UInt64 = uint64_t;
#endif
using LargestInt = Int64;
using LargestUInt = UInt64;
#define JSON_HAS_INT64
#endiftemplate <typename T>
// JSONCPP_USING_SECURE_MEMORY 為true,使用SecureAllocator<T>, 為false,使用std::allocator<T>
using Allocator = typename std::conditional<JSONCPP_USING_SECURE_MEMORY, SecureAllocator<T>, std::allocator<T>>::type;
using String = std::basic_string<char, std::char_traits<char>, Allocator<char>>;
using IStringStream = std::basic_istringstream<String::value_type, String::traits_type, String::allocator_type>;
using OStringStream = std::basic_ostringstream<String::value_type, String::traits_type, String::allocator_type>;
using IStream = std::istream;
using OStream = std::ostream;
}

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

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

相關文章

《C++ 入門:第一個小程序》

《C 入門&#xff1a;第一個小程序》 在學習 C 的旅程中&#xff0c;編寫第一個小程序是一個令人興奮的時刻。它就像打開一扇通往新編程世界的大門&#xff0c;讓我們初步領略 C 的魅力。 C 是一種強大而靈活的編程語言&#xff0c;廣泛應用于各種領域&#xff0c;從系統編程…

python 方向梯度直方圖(HOG)算法 【附兩種實現方法并可視化】

目錄 一、概述1.1 算法定義1.2 實現過程二、方法1(skimage庫)2.1 代碼實現2.2 結果示例三、方法2(cv2庫)3.1 代碼實現3.2 結果示例四、結果對比?? 結果預覽 一、概述 1.1 算法定義 方向梯度直方圖(Histogram of Oriented Gradient,HOG):是應用在計算機視覺和圖像處…

Telegram Bot、小程序開發(三)Mini Apps小程序

文章目錄 一、Telegram Mini Apps小程序二、小程序啟動方式三、小程序開發小程序調試模式初始化小程序Keyboard Button Mini Apps 鍵盤按鈕小程序【依賴具體用戶信息場景,推薦】**Inline Button Mini Apps內聯按鈕小程序**initData 的自動傳遞使用內聯菜單時候哪些參數會默認傳…

LLM微調

文章目錄 一. 常見微調分類1.1 全量微調&#xff08;FFT&#xff1a;Full Fine-tuning&#xff09;1.2 參數高效微調(PEFT&#xff1a;Parameter-Efficient Fine-Tuning)1.3 指令微調&#xff08;IFT&#xff1a;Instructional Fine-tuning&#xff09;1.3.1 Hard prompt1.3.2 …

Docker存儲目錄問題,如何修改Docker默認存儲位置?(Docker存儲路徑、Docker存儲空間)etc/docker/daemon.json

文章目錄 如何更改docker默認存儲路徑&#xff1f;版本1&#xff08;沒測試&#xff09;版本2&#xff08;可行&#xff09;1. 停止 Docker 服務&#xff1a;2. 創建新的存儲目錄&#xff1a;3. 修改 Docker 配置文件&#xff1a;4. 移動現有的 Docker 數據&#xff1a;5. 重新…

Java-svg格式的oss圖片鏈接轉換為png格式圖片字節流

一、引入依賴 <!--svg轉其他格式依賴--> <dependency><groupId>org.apache.xmlgraphics</groupId><artifactId>batik-transcoder</artifactId><version>1.14</version> </dependency> <dependency><groupId&g…

什么樣的服務器是合乎直銷網站標準

現在社會的發展,有著越來越多的人想要利用互聯網來做直銷。做好直銷行業系統解決方案離不開好的服務器支持,服務器的的穩定性和速度是直接影響網站后期運作,可以看做是網站的根基。 做網站直銷選擇租用服務器需要注意的幾點要素 一些大的直銷互聯網公司如安利、雅芳、康寶萊、玫…

【人工智能】自然語言處理(NLP)的突破,關注NLP在機器翻譯、情感分析、聊天機器人等方面的最新研究成果和應用案例。

自然語言處理&#xff08;NLP&#xff09;作為人工智能的一個重要分支&#xff0c;近年來取得了顯著的突破&#xff0c;特別在機器翻譯、情感分析、聊天機器人等領域取得了顯著的研究成果和廣泛的應用。以下是對這些領域最新研究成果和應用案例的概述&#xff0c;并附帶相應的代…

域名解析記錄與服務器源IP的探索

在互聯網中&#xff0c;域名和IP地址是進行網絡通信的基礎。用戶通常通過域名來訪問網站或服務&#xff0c;而實際的數據交換則發生在IP地址之間。域名解析&#xff08;DNS解析&#xff09;是將易于記憶的域名轉換為計算機可識別的IP地址的過程。本文將探討如何通過域名解析記錄…

Uniapp自定義動態加載組件(2024.7更新)

1.本次介紹如何使用uniapp實現自定義動態加載Loading的組件&#xff0c;可以gif格式&#xff0c;也可以mp4格式等; 編寫自定義Loading組件(CustomLoader.vue)&#xff1b;組件中含有“動態接收圖片路徑”&#xff0c;“10秒超時未false則自動斷開關閉Loading”&#xff1b;在全…

【JavaScript 算法】廣度優先搜索:層層推進的搜索策略

&#x1f525; 個人主頁&#xff1a;空白詩 文章目錄 一、算法原理二、算法實現三、應用場景四、優化與擴展五、總結 廣度優先搜索&#xff08;Breadth-First Search, BFS&#xff09;是一種用于遍歷或搜索圖或樹數據結構的算法。該算法從起始節點開始&#xff0c;逐層向外擴展…

小程序-2(WXML數據模板+WXSS模板樣式+網絡數據請求)

目錄 1.WXML數據模板 數據綁定 事件綁定 小程序中常用的事件 事件對象的屬性列表 target和currentTarget的區別 bindtap的語法格式 在事件處理事件中為data中的數據賦值 事件傳參與數據同步 事件傳參 bindinput的語法綁定事件 文本框和data的數據同步 條件渲染 w…

《向量數據庫指南》——使用 Grafana 和 Loki 搭建 Milvus Cloud日志查詢系統

本教程將介紹如何設置 Grafana 和 Loki 來有效監控您的 Milvus Cloud實例。 Milvus Cloud是一款分布式向量數據庫,可高效存儲、索引和管理萬億級 Embedding 向量,是搭建 AI 和 ML 應用的首選向量數據庫系統。 Grafana 是一個開源的指標監控平臺,提供可視化的指標和日志…

5,SSH 端口轉發

SSH 端口轉發 簡介 SSH 除了登錄服務器&#xff0c;還有一大用途&#xff0c;就是作為加密通信的中介&#xff0c;充當兩臺服務器之間的通信加密跳板&#xff0c;使得原本不加密的通信變成加密通信。這個功能稱為端口轉發&#xff08;port forwarding&#xff09;&#xff0c…

SpringCloud | 單體商城項目拆分(微服務)

為什么要進行微服務拆分&#xff1f; 在平常的商城項目中&#xff0c;我們一般的項目結構模塊都是將各種業務放在同一個項目文件夾&#xff0c;比如像&#xff1a; 用戶&#xff0c;購物車&#xff0c;商品&#xff0c;訂單&#xff0c;支付等業務都是放在一起&#xff0c;這樣…

thinkphp:數據庫多條件查詢

一、使用if條件限制查詢條件 $query Db::table(wip_operation_plan)->alias(d)->join([wip_jobs_all > a], a.wip_entity_name d.wip_entity_name)->join([sf_item_no > c], a.primary_itemc.item_no)->field(d.*,c.item_no as item_no,c.item_name as i…

線上觀看 3 萬+!「智能運維MeetUp」精彩回顧,探討智能體構建新方向

龍蜥社區“走進系列”第 11 期走進中興通訊-智能可觀測運維技術 MeetUp 于成都圓滿結束&#xff0c;由中興通訊聯合龍蜥社區系統運維聯盟&#xff08;SOMA&#xff09;&#xff08;以下簡稱“聯盟”&#xff09;共同舉辦。本次活動現場匯聚了阿里云、諧云科技、乘云數字、中興通…

MySQL數據庫day7.11

一&#xff0c;SQL概述 1.1 SQL語句語法 MySQL 數據庫的 SQL 語句不區分大小寫&#xff0c;關鍵字建議使用大寫&#xff0c; 以分號結尾。例如&#xff1a; SELECT * FROM user; 使用 /**/ 、 -- 、 # 的方式完成注釋 /* 多行注釋 */ -- 單行注釋 # 單行注釋 SELECT * FRO…

vue2 ant-design select組件自定義下拉框, dropdownRender 使用,以及遇到的坑

業務需求&#xff1a;下拉框需要滿足用戶可輸入篩選 和 點擊右側 字符按鈕 #A-Z進行用戶選擇 1、基礎頁面代碼 <div><a-selectstyle"width: 100%"placeholder"請選擇客戶"allow-clearshow-search:filter-option"false":not-found-con…

計算機硬件---如何更新自己電腦的BLOS

1找官網 例如“我使用的是HP&#xff08;惠普&#xff09;品牌的電腦”我只需要在瀏覽器上搜索“惠普官網”或“惠普-blos更新” 就可以看到&#xff0c;來自官網中更新blos的信息 2.有些品牌要查序列號該怎么辦呢&#xff1f; 有許多方法可以查詢&#xff0c;例如&#xf…