2017-02-21 68 views
4

通常在一個動態類型的編程語言中,對象struct有一個用於標識對象類型的標籤字段。 例如:有什麼方法可以在C語句中使用指針嗎?

struct myObject { 
    int tag; 
    ... 
} 

所以很容易進行使用基於標籤領域的switch語句不同的動作。 例如:

​​

在我的情況,而不是我使用了指向表示該對象的類一個void * isa指針整型標記字段。一切都很好,希望不要使用優雅的switch語句,我不得不使用一系列if/else語句。例如:

if (obj->isa == class_integer) { 
    ... 
} else if (obj->isa == class_string) { 
    ... 
} else if (obj->isa == class_func) { 
    ... 
} 

我知道,我不能使用C開關語句中三分球,但我想,如果我可以使用一些聰明的技巧,以加速比該系列的if語句。

+0

更換switch什麼樣的 「加速」 的?你的編譯器不是已經爲你做了嗎? –

+2

您不能將非常量表達式用作'case'標籤。 –

+0

@EugeneSh。我猜OP已經意識到了這一點? :) –

回答

14

具有isa指針的美麗首先是完全免除開關語句的能力。

考慮一個開關:

switch (obj->tag) { 
    case OBJ_INTEGER: do_something_int(obj); break; 
    case OBJ_STRING: do_something_str(obj); break; 
    case OBJ_FUNC: do_something_func(obj); break; 
} 

假設isa指針指向一些struct你自己 - 說,struct dyn_type。一個函數指針添加到您的struct,像這樣:

typedef void (*ProcessPtr)(dyn_obj * obj); 

struct dyn_type { 
    ... // fields of your current struct 
    ProcessPtr process; 
}; 

設置processdo_something_intOBJ_INTEGERdo_something_strOBJ_STRING等,現在你可以用

((struct dyn_type*)obj->isa)->process(obj) 
+1

很快你就會發明C++。 :) – rici

+0

這是一個普通的OO模式:如果您發現自己使用查看對象類/ isa的條件/開關語句,那是一種代碼異味。你應該在99%的案例中調用一個方法。 – uliwitness

相關問題