2008-10-09 25 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++; 
} 

很抱歉,如果它是一个有点'生'。直接从我们的代码粘贴;-)