2008-10-09 21 views

回答

13
/* define a typedef for function_t - functions that return void */ 
/*  and take an int and char parameter */ 

typedef void function_t(int param1, char param2); 

/* declare some functions that use that signature */ 

function_t foo; 
function_t bar; 

現在,當您定義函數時,如果它們不使用與typedef中相同的簽名,將會出現錯誤。

void foo(int x, char c) 
{ 
    /* do some stuff */ 

    return; 
} 

/* this will result in a compiler error */ 
int bar(int x, char c) 
{ 
    /* do some stuff */ 

    return 1; 
} 

至於你的新問題(添加零八年十月二十零日):「另外,有沒有爲傳遞到該函數的typedef指定默認值的方法嗎?」

不,沒有辦法將默認參數添加到typedef。當然不是在C中,它根本不支持默認參數。即使在C++中,也不能這樣做,因爲參數的默認值不是該類型的一部分。實際上,從基類中覆蓋虛擬方法的類可以爲默認參數指定不同的值(或者甚至完全刪除默認參數) - 但是,這是不應該一般地完成的,因爲它只會導致混淆(http://www.gotw.ca/gotw/005.htm)。

如果您正在使用C++,你也許能得到您想要使用的一個行爲(或組合)以下:

  • 抽象基類
  • 超載
  • 模板函數

但它會很難提出好的建議,而無需瞭解EXAC更多的細節真正想要完成的是什麼。而且我認爲結果很可能相當不好。

+0

哇,我從來沒有那樣,只是作爲函數指針。你可以重用函數定義的function_t嗎? – quinmars 2008-10-09 18:30:33

0

這類似於一個函數指針是如何工作的:

// Declaration of function with int arg returning int 
typedef int (*CALLBACK)(int); 

//Definition 
int myFunc(int arg) 
{ 
    return 0; 
} 

// Function pointer usage 
CALLBACK pFunc = myFunc; 
0

我不認爲你可以直接做到這一點,但你可以定義一個函數指針類型,然後收集所有功能集成到一個數組。編譯器會讓你知道哪些不匹配。

typedef void (*MethodSig)(int, int); 

static MethodSig x[] = { fnA, fnB, ... }; 

或者使用宏來聲明函數簽名

#define MyFunc(X) void X(int a, int b) 

這樣,他們都將是相同的。

0

你不能真正阻止任何人使一個函數有任何簽名。但是你可以控制你要打的電話。所以我認爲這是你想要的。

有將調用任意函數的函數以函數的指針作爲參數。既然你提到的typedef,您可以在程序中早期定義的類型定義,像這樣:

假設你只想要簽名「無符號短id_for_allowed_functions(INT X,字符* Y)」的功能:

typedef unsigned short (*id_for_allowed_functions)(int, char*); 

然後,您的通話功能:

void calling_function (id_for_allowed_function x) { (*x)(3, "bla"); } 

並且提供函數foo它:

unsigned short foo(int x, char* y) { /* ... */ } 
calling_function(&foo); 
0

下面是創建映射到簡單字符串的函數列表的示例。

首先是類型定義:

typedef GenList *(*DBLISTLOADER)(Database *pDB, char *quellCD, char *profilName); 
typedef ObjDescription *(*DBCOLUMNLOADER)(); 

typedef struct dbinfo 
{ 
    char *dbName; 
    DBLISTLOADER dbListLoader; 
    DBCOLUMNLOADER dbColumnLoader; 
    char *options; 
} DBINFO; 

則映射表:

DBINFO dbInfoList[] = 
{ 
    { "SRCDOC", loadSRCDOC,  colSRCDOC,  "q" }, 
    { "PRF_CD", loadPRF_CD,  colPRF_CD,  "" }, 
    { "MEDIA", loadMEDIA,  colMEDIA,  "" }, 

    { NULL,  NULL,   NULL } 
}; 

我們從該表中查找一個函數並調用它:

while (dbInfoList[i].dbName != NULL) 
{ 
    if (strcmp(dbInfoList[i].dbName, szDatabase) == 0) 
    { 
     return (dbInfoList[i].dbListLoader)(pDB, quellCD, profilName); 
    } 

    i++; 
} 

很抱歉,如果它是一個有點'生'。直接從我們的代碼粘貼;-)