的解析我試圖解析與嵌套結構的二進制文件格式。在程序的僞代碼,該過程將如下這樣:嵌套結構和對象模型
// A structure contains:
// tag | oneof(a, b, c) | oneof(oneof(aa, ab, ac), oneof(ba, bb, bc), oneof(ca, cb, cc))
PROCEDURE parse() {
RECORD read_type;
read_tag(read_type);
if (read_type == TYPE_A) {
read_a(read_type);
if (read_type == TYPE_AA) {
read_aa();
} else if (read_type == TYPE_AB) {
read_ab();
} else if (read_type == TYPE_AC) {
read_ac();
}
} else if (read_type == TYPE_B) {
// see above
} else if (read_type == TYPE_C) {
// see above
}
}
的外部結構例如AA不能在不脫離它的父對象A,而這又需要它的標籤/標頭解釋上下文來解釋。使用這些結構時,處理包含A的結構是有意義的,這些結構包含AA等,但不能是結構的A或AA部分。
我的問題是那麼如何創建此過程的類模型。如果該結構是:
class Base;
class A: Base;
class B: Base;
class C: Base;
class AA: A;
class AB: A;
class AC: A;
// ...
在這種情況下,AA可能被理解爲這樣的:
AA::AA(): A() {
read_aa();
}
A::A(): Base() {
read_a();
}
Base::Base() {
read_tag();
}
然而,問題是,這是不可能知道的派生類對象,而不構建首先構造基礎對象。這可以通過使用構造函數AA :: AA(A *)來複制構造其父項,但這看起來像是一種不必要的低效率。此外,這將需要一個外部工廠功能,諸如:
Base *read_object() {
Base *base = new Base();
if (b->tag_type == TYPE_A) {
A *a = new A(base);
if (a->tag_type == TYPE_AA) {
return new AA(a);
} else if (a->tag_type == TYPE_AB) {
// ...
} else if (a->tag_type == TYPE_AC) {
// ...
}
} else if (b->tag_type == TYPE_B) {
// ...
} else if (b->tag_type == TYPE_C) {
// ...
}
}
另一種選擇是爲具有指結構的子區域,如類:
class CompleteStructure;
class StructureA;
class StructureB;
class StructureC;
class StructureAA;
class StructureAB;
class StructureAC;
// ...
class CompleteStructure {
union {StructureA a, StructureB b, StructureC c} sub;
}
class StructureA {
CompleteStructure *parent;
union {StructureAA aa, StructureAB ab, StructureAC ac} sub;
}
class StructureAA {
StructureA *parent;
}
在這種情況下,該構造函數CompleteStructure :: CompleteStructure()會讀取標記,然後構造StructureA,StructureB或StructureC中的一個,然後構造它自己的子結構。與此相關的問題是,每個子結構都需要明確引用其父項,以便「投射」層次並實現其方法/功能。
是這些方法比其他的更好的空間/時間效率和「清潔」的名詞之一?有沒有優越的第三種方法?
編輯: 要到下面的兩個答案迴應,問題是雙方關於分析和對象行爲。我最初的目標僅僅是從文件中讀取結構,打印出它們的字段,然後按照相同的順序將它們寫回到磁盤。稍後,還會有額外的目標,例如查找A派生結構的所有實例並按特定字段對其進行排序或檢查非法結構組合(例如,同時具有BA和BB)。
EDIT2: 這是我參考的一個結構(帶有通用字段名稱)的示例模式。 u8/16/32是指整數類型,sz是一個C字符串,大寫名稱是需要讀取的字段,常量前綴爲下劃線。
DEF AA {
// Identifies and deliminates complete records.
TAG {
u32 SYNC_CODE = 0xFFFFFFFF;
}
// Metadata for high level identification of data.
A {
u32 TYPE = __TYPE_A;
u16 CATEGORY = __CATEGORY_1; // A defines the "category" of the following file data
u32 NUM_OF_KV_PAIRS;
for (int i = 0; i < NUM_OF_KV_PAIRS; ++i) { // unspecified metadata
sz KEY;
sz VALUE;
}
u8 HAS_EXTENSION_FLAG = true; // indicates presence of next record
if (!HAS_EXTENSION_FLAG) {
DEFAULT_PARAMS; // legacy
}
}
// Indicates a specific data layout and version.
AA {
u32 TYPE = __TYPE_AA;
u8[16] ACCESS_KEY;
u32 NUM_OFFSETS;
for (int i = 0; i < NUM_OFFSETS; ++i) {
// stuff
}
}
}
我沒有得到_「與此相關的問題是,每個子結構都需要明確引用其父級以便」投射「層次結構」_您能詳細說明一點嗎?爲什麼一個子結構讓我們說AA需要知道任何關於它的超級結構A的例子? –
AA中的字段指的是先前結構中的初始化結構來定義它們的語義。此外,爲了類型安全,人們可能希望通過其特定類型來引用完整的結構,例如函數'process(AA a){do_something(a.complete_structure()); }'。 – user2363399
_HAS_EXTENSION_FLAG = true; //表示下一個記錄的存在_這是關於AA結構的存在還是其他意義? –