我只需要用 C 和 C 做一個大型專案,沒有外部庫(SDL 除外)。我開始尋找在 C 中做某種類的方法,是什么導致我這樣做:
typedef void (*voidFunction)(void);
typedef struct{
int id;
voidFunction printId;
} Object;
Object *new_Object(int id){
Object *newObject = malloc(sizeof(Object));
newObject->id = id;
void printId(){
static Object *this = NULL;
if(!this) this = newObject;
printf("%d\n", this->id);
};
newObject->printId = printId;
return newObject;
}
int main(){
Object *object = new_Object(5);
object->printId();
object->id ;
object->printId();
return 0;
}
主要輸出:
5
6
所以這行得通,但它似乎合理嗎?如果我將這種架構用于大型專案,我是否應該期待反彈?也許我在沒有意識到的情況下輸入了分配的記憶體?
uj5u.com熱心網友回復:
在 C 中實作多型性的技術由來已久,請查看此答案,例如https://stackoverflow.com/a/351745/4433969
您的實作似乎被破壞了。嵌套函式是非標準擴展。我也對靜態這個變數有疑問。
uj5u.com熱心網友回復:
非標準嵌套函式printId使用不當。在 GCC 檔案中嵌套函式可以閱讀:
如果您在包含函式退出后嘗試通過其地址呼叫嵌套函式,那么一切都會崩潰。
嵌套函式通過蹦床呼叫,蹦床是位于堆疊上的一小段可執行代碼。此代碼在父函式退出時無效。
盡管函式不參考任何區域變數,但代碼可能會起作用。編譯器可能會避免蹦床,而是創建一種“匿名”靜態函式。
慣用的解決方案應該將指向“物件”的指標作為引數,而不是使用靜態變數。
typedef struct Object {
int id;
void (*printId)(struct Object*);
} Object;
void printId(Object *this){
printf("%d\n", this->id);
};
...
object->printId(object);
uj5u.com熱心網友回復:
使用 astruct來組織資料以進行批量處理是有好處的。但是,使用函式指標而不是直接呼叫函式的唯一優點是:
- 允許函式指標針對物件的不同實體指向具有相同型別的不同函式。
- 從聯結器中隱藏“成員”函式定義。例如,該函式
printId可以static在包含“建構式”定義的模塊中宣告new_Object。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/411843.html
標籤:
