C++ 模板缺乏執行期型別資訊(RTTI 僅支援多型基類),難以直接序列化容器內的多型物件。Vczh Library 採用宏標註欄位 + 執行期型別登記機制,實現非侵入式、支援多型與容器的高效序列化。
class Node : public VL_SerializableObject {
public:
typedef VL_AutoPtr<Node> Ptr;
virtual VUnicodeString ToString(VUnicodeString Prefix) = 0;
};
class NumberNode : public Node {
public:
VInt Number;
NumberNode() { VL_SERIALIZABLE_FIELD(NumberNode, Number); }
VUnicodeString ToString(VUnicodeString Prefix) override {
return Prefix + VUnicodeString(Number);
}
};
class IdNode : public Node {
public:
VUnicodeString Id;
IdNode() { VL_SERIALIZABLE_FIELD(IdNode, Id); }
VUnicodeString ToString(VUnicodeString Prefix) override {
return Prefix + Id;
}
};
class ListNode : public Node {
public:
VL_List<Ptr, false, Node*> Children; // 容器支援多型指標
ListNode() { VL_SERIALIZABLE_FIELD(ListNode, Children); }
VUnicodeString ToString(VUnicodeString Prefix) override {
VUnicodeString Result = Prefix + L"List {\r\n";
for (VInt i = 0; i < Children.GetCount(); ++i) {
Result += Children[i] ? Children[i]->ToString(Prefix + L" ") + L"\r\n"
: Prefix + L" <NULL>\r\n";
}
return Result + Prefix + L"}";
}
};
void InitializeSerializer(VL_Serializer& Serializer) {
VL_SERIALIZABLE_CLASS(&Serializer, NumberNode);
VL_SERIALIZABLE_CLASS(&Serializer, IdNode);
VL_SERIALIZABLE_CLASS(&Serializer, ListNode);
}
Node::Ptr BuildNode() {
ListNode* Root = new ListNode;
Root->Children.Add(new NumberNode{10});
ListNode* List = new ListNode;
List->Children.Add(new NumberNode{20});
List->Children.Add(nullptr); // 支援空指標
List->Children.Add(new IdNode{L"Serialization"});
Root->Children.Add(List);
Root->Children.Add(new IdNode{L"VCZH"});
return Root;
}
void ServerMain() {
VL_Serializer Serializer; InitializeSerializer(Serializer);
VL_SocketServer Server(vspTCP, L"8000", false);
if (Server.IsSuccess()) {
VL_ServerSocket* Socket = Server.WaitForConnection();
if (Socket) {
Node::Ptr MyNode = BuildNode();
WriteCommonObject(Socket->GetWriterStream(), Serializer.Serialize(MyNode.Object()));
delete Socket;
}
}
}
void ClientMain() {
VL_Serializer Serializer; InitializeSerializer(Serializer);
VL_ClientSocket Socket(vspTCP, L"127.0.0.1", L"8000");
if (Socket.Connect()) {
Node::Ptr MyNode = Serializer.Deserialize(ReadCommonObject(Socket.GetReaderStream()));
GetConsole()->Write(MyNode->ToString(L""));
}
}
void vlmain() {
VL_SynEvent Event;
switch (Event.Create(false, false, L"VCZH")) {
case VL_SynObject::arSucceed: ServerMain(); break; // 首次啟動 → Server
case VL_SynObject::arAlreadyExists: ClientMain(); break; // 二次啟動 → Client
case VL_SynObject::arFail: /* 錯誤處理 */ break;
}
}
List {
10
List {
20
<NULL>
Serialization
}
VCZH
}
VL_SerializableObject,宏登記具體型別,反序列化自動還原動態型別。VL_List<Ptr> 直接序列化智慧指標容器,保留物件擁有權語意。nullptr,序列化/反序列化正確保留。VL_SynEvent 實現單一執行檔自動協商 Server/Client 角色。