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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

一种向后兼容的C++结构体设计

發布時間:2023/12/18 c/c++ 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一种向后兼容的C++结构体设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

問題產生的背景:
有時候,我們需要維護老舊代碼。這些代碼經常因為需求變更而變化。最常見的升級就是接口的升級,諸如增加新的函數接口、擴展函數的參數、擴展協議等等。在此我們討論一種較為少見的情形,即存儲于設備中的一段二進制結構的升級。這種情況類似于網絡通訊中的序列化,但又有所不同。關于如何設計序列化結構的文章有許多,我們在此不做討論。
設計目標:
1. 為了兼容老版本的結構體
2. 為了支持內存拷貝初始化
3. 版本號的支持
4. 盡量少的代碼修改

假設我們第一次(舊)的數據結構如下:

struct Old{ int i; };

首先,我們期望能對后續升級的結構體帶有版本號。最簡單的想法是在結構體中添加一個int類型的版本信息。但是,當我們深入考慮時,首先想到的一個問題就是,我們該如何從一段內存區中得到這個版本信息。如果我們添加了版本字段,那么我們首先需要找到這個字段,得到其版本號,然后再把這個緩沖區的數據轉換成對應版本的數據結構。顯然,我們是知道這個字段所在的內存偏移量的。于是我們的實現代碼大概如下:

struct V1{ int i; int version; //version==1 }; struct V2{ int i; int version; //version==2 int j; }; // unsigned char* buff=new unsigned char[100]; int len = 0; getStruct(buff,&len); int* pVersion = &(buff[4]);

于是我們拿到了結構體的版本號,可以根據版本號得到具體的數據類型了。然而仔細考察一下可以發現,實際上我們并不需要這個版本號,因為每一次升級,數據結構都是在原有的基礎上添加的,因此這個結構體的長度會隨著版本號的增加而增加,所以我們可以利用這個結構體的長度(注意對其可能導致長度相同的問題),來作為區分版本的關鍵。于是,我們省去了一個int的長度。

為了能夠區分版本,我們在上面的結構體名字當中使用了諸如1、2之類的標志。實際上,我們可以利用C++語法的模板來代替這些常量,以確保代碼的易讀性。于是結構體的定義更改為:

template<int VERSION> struct V{}; template<> struct V<0>{ int i; } template<> struct V<1>{ int i; int j; };

為了保證能夠與C的結構體兼容,我們還需要保證我們的結構體是POD類型。因此我們不能在結構體中定義任何初始化函數,也不能使用繼承。為了保證這一規范,我們采用靜態斷言,提前為未來的升級做約束:

static_assert(std::is_pod<V<0> >::value==true,"V<0> is not a POD type"); static_assert(std::is_pod<V<1> >::value==true,"V<1> is not a POD type"); static_assert(std::is_pod<V<2> >::value==true,"V<2> is not a POD type"); static_assert(std::is_pod<V<3> >::value==true,"V<3> is not a POD type");

于是我們可以這樣去使用這個結構體:

getStruct(buff,&len); switch(len){ case sizeof(V<0>): {V<0>* pV=(V<0>*)buff;} break; case sizeof(V<1>): {V<1>* pV=(V<1>*)buff;} break;
}

從C++的角度來看,上述思路還有許多改進的地方,在此僅做拋磚引玉,歡迎各位的討論

轉載于:https://www.cnblogs.com/webbery/p/10236152.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的一种向后兼容的C++结构体设计的全部內容,希望文章能夠幫你解決所遇到的問題。

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