既然你说的是多态,那么是的,你可以,在C+出现之前,我们就在做类似的事情。
基本上,您使用的是struct若要同时保存数据和指向该数据的相关函数的函数指针列表,请执行以下操作。
因此,在一个通信类中,您将拥有一个打开、读、写和关闭调用,这些调用将作为结构中的四个函数指针来维护,以及对象的数据,如下所示:typedef struct {
int (*open)(void *self, char *fspec);
int (*close)(void *self);
int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
// And data goes here.} tCommClass;tCommClass commRs232;commRs232.open = &rs232Open;: :commRs232.write = &rs232Write;
tCommClass commTcp;commTcp.open = &tcpOpen;: :commTcp.write = &tcpWrite;
当然,上面的代码段实际上是在一个“构造函数”中,例如rs232Init().
当您从该类“继承”时,只需将指针更改为指向您自己的函数。调用这些函数的每个人都会通过函数指针来实现这一点,从而给出您的多态性:int stat = (commTcp.open)(commTcp, "bigiron.box.com:5000");
有点像手动表。
您甚至可以通过将指针设置为NULL来拥有虚拟类-这种行为与C+(运行时的核心转储而不是编译时的错误)略有不同。
下面是演示它的一段示例代码。首先是顶级的阶级结构:#include // The top-level class.typedef struct sCommClass {
int (*open)(struct sCommClass *self, char *fspec);} tCommClass;
然后我们有TCP‘子类’的函数:// Function for the TCP 'class'.static int tcpOpen (tCommClass *tcp, char *fspec) {
printf ("Opening TCP: %s\n", fspec);
return 0;}static int tcpInit (tCommClass *tcp) {
tcp->open = &tcpOpen;
return 0;}
HTTP也是如此:// Function for the HTTP 'class'.static int httpOpen (tCommClass *http, char *fspec) {
printf ("Opening HTTP: %s\n", fspec);
return 0;}static int httpInit (tCommClass *http) {
http->open = &httpOpen;
return 0;}
最后是一个测试程序来展示它的作用:// Test program.int main (void) {
int status;
tCommClass commTcp, commHttp;
// Same 'base' class but initialised to different sub-classes.
tcpInit (&commTcp);
httpInit (&commHttp);
// Called in exactly the same manner.
status = (commTcp.open)(&commTcp, "bigiron.box.com:5000");
status = (commHttp.open)(&commHttp, "http://www.microsoft.com");
return 0;}
这将产生输出:Opening TCP: bigiron.box.com:5000Opening HTTP: http://www.microsoft.com
因此,您可以看到不同的函数正在被调用,这取决于子类。