Boost.Serialization 透過運算符重載實現串流讀寫,而本庫採用「成員變數註冊」機制:在建構函數中註冊可序列化欄位,自動生成讀寫邏輯,並支援與 XML 雙向轉換。雖效能非極致、有侵入式代碼,但適合特定領域需求 (配置持久化、狀態儲存、網路協議)。
class TestTree : public VL_SerializableObject {
public:
VInt IntegerMember;
VUnicodeString StringMember;
VL_AutoPtr LeftTree;
VL_AutoPtr RightTree;
TestTree() {
VL_REGISTER_SERIALIZABLE_FIELD(TestTree, IntegerMember);
VL_REGISTER_SERIALIZABLE_FIELD(TestTree, StringMember);
VL_REGISTER_SERIALIZABLE_FIELD(TestTree, LeftTree);
VL_REGISTER_SERIALIZABLE_FIELD(TestTree, RightTree);
}
};
VL_Serializer Serializer;
VL_REGISTER_SERIALIZABLE_CLASS(&Serializer, TestTree);
// 建構物件樹
VL_AutoPtr Root = new TestTree;
Root->IntegerMember = 10;
Root->StringMember = L"Root";
VL_AutoPtr Left = new TestTree;
Left->IntegerMember = 20; Left->StringMember = L"Left";
Root->LeftTree = Left;
VL_AutoPtr Right = new TestTree;
Right->IntegerMember = 30; Right->StringMember = L"Right";
Root->RightTree = Right;
// 序列化 → XML
VL_CommonObject SerializedObject = Serializer.Serialize(Root.Object());
VL_XMLDocument Document;
Document.GetRootElement()->SetName(L"SerializedObject");
SerializedObject.SaveToXML(Document.GetRootElement());
VL_FileStream Stream(FileName, VL_FileStream::vfomWrite);
Document.Save(&Stream, true);
class FieldSerializerBase {
public:
virtual void Serialize(VL_Serializer* serializer, VL_CommonObject& classObject) = 0;
protected:
VUnicodeString FFieldName;
};
// 基本型別特化
template
class FieldSerializer<_Type, FIELD> : public FieldSerializerBase { ... };
// 指標型別
template
class FieldSerializer<_Type, _Field*> : public FieldSerializerBase { ... };
// 智慧指標 VL_AutoPtr
template
class FieldSerializer<_Type, VL_AutoPtr<_Field>> : public FieldSerializerBase { ... };
class VL_Serializer {
class ClassSerializerBase {
virtual bool Accept(VL_SerializableObject* obj) = 0;
virtual VUnicodeString GetClassTypeName() = 0;
};
template
class ClassSerializer : public ClassSerializerBase {
bool Accept(VL_SerializableObject* obj) override {
return dynamic_cast<_Type*>(obj) != nullptr;
}
};
List FClassSerializers;
void RegisterClass(ClassSerializerBase* cs) { FClassSerializers.Add(cs); }
ClassSerializerBase* SelectClass(VL_SerializableObject* obj) { ... }
VL_CommonObject Serialize(VL_SerializableObject* obj) { ... }
};
#define VL_REGISTER_SERIALIZABLE_CLASS(SERIALIZER, CLASS) \
do { (SERIALIZER)->RegisterClass(new VL_Serializer::ClassSerializer(L#CLASS)); } while(0)
#define VL_REGISTER_SERIALIZABLE_FIELD(CLASS, FIELD) \
do { AddFieldSerializer(this, &CLASS::FIELD, L#FIELD); } while(0)
SerializeVL_CommonObject::SaveToXML 遞迴生成 DOM| 優點 | 缺點 |
|---|---|
| 聲明式欄位註冊,無樣板代碼 | 侵入式:需繼承基類、建構函數註冊 |
| 原生支援 XML 互轉 | 效能非極致 (中間物件、動態分配) |
| 支援巢狀物件、智慧指標遞迴 | 不支援版本演進、Schema 驗證 |
| 型別安全 (編譯期檢查欄位指標) | 依賴自定義型別系統 (VInt, VUnicodeString...) |
適用:工具類專案、配置系統、遊戲存檔、特定協議編解碼。
std::variant/std::any 替代 VL_CommonObjectnlohmann::json / cereal / Boost.Serialization 等成熟庫替代