提问人:Luchian Grigore 提问时间:7/27/2011 最后编辑:CommunityLuchian Grigore 更新时间:7/27/2011 访问量:12733
C 语言中的虚函数 [重复]
Virtual functions in C [duplicate]
问:
可能的重复:
如何在 C 中实现 C++ 虚函数
在 C++ 中,类和结构之间的唯一区别是默认访问级别。因此,您可以在结构中拥有虚拟函数,从结构继承等等。我的问题是,你也可以用 C 语言做到这一点吗?
答:
不,你不能。“虚拟”不是 C 词汇的一部分,“访问级别”也不是
评论
virtual
virtual
virtual
virtual
您可以使用存储在结构中的函数指针执行“虚拟函数”。对于固有结构,您可以将一个结构嵌入到另一个结构中,但语法将再次与您预期的不同。你可以用 C 语言编写面向对象的程序(经典的例子是 unix file/socket/...API),但语法非常笨拙。
相关答案在这里: https://stackoverflow.com/search?q=C+virtual+functions
评论
struct
interface
virtual
C 没有虚拟方法的本机语法。但是,您仍然可以通过模仿 C++ 实现虚拟方法的方式来实现虚拟方法。C++ 为每个虚拟方法在每个类中存储一个指向函数定义的附加指针。因此,您可以简单地将函数指针添加到结构中以模拟虚拟方法。
例如
#include <stdio.h>
#include <stdlib.h>
int f2(int x)
{
printf("%d\n",x);
}
typedef struct mystruct
{
int (*f)(int);
} mystruct;
int main()
{
mystruct *s=malloc(sizeof(mystruct));
s->f=f2;
s->f(42);
free(s);
return 0;
}
评论
int (*f)(int x)=NULL;
s.f
NULL
C 结构不能有行为。他们只能拥有数据。
请参阅 http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=tenBestQuestions 了解 C 结构和 C++ 结构之间的差异。 它写在第二个问题中。
C++ 结构与 C++ 类不同于 C 结构。这只是一个类比。
另外,在C语言中没有继承这样的东西。如果没有继承,你会用虚拟函数做什么?
评论
您可以使用函数指针模拟虚拟函数。例如
struct foo
{
void(*bar)(struct foo*, int, int);
};
void default_bar ( struct foo * f, int a, int b )
{
printf("bar(%d,%d)\n", a, b);
}
void setup_foo ( struct foo * f )
{
f->bar = &default_bar;
}
然后,你可以用类似的东西来“子类化”结构:
struct meh
{
/* inherit from "class foo". MUST be first. */
struct foo base;
int more_data;
};
/* override "method bar". */
struct custom_bar ( struct foo * f, int a, int b )
{
struct meh * m = (struct meh*)f;
printf("custom_bar(%d,%d)\n", a, b);
}
void setup_meh ( struct meh * m )
{
setup_foo(&m->base);
m->bar = &custom_bar;
}
所有这些都是劳动密集型且容易出错的,但这是可以做到的。这种类型的“继承”和“覆盖”实现是一些知名 C 库(包括 和 )中的常见做法。如果您对标准 C I/O 不满意,他们使用此技术允许您覆盖 I/O 过程。jpeglib
libpng
编辑:如评论中所述,其中一些代码依赖于(官方)非标准行为,这些行为“恰好”适用于大多数编译器。主要问题是代码假定(例如,成员的偏移量为 0)。如果不是这种情况,则强制转换会导致未定义的行为。若要解决此问题,可以添加一个额外的指针,如下所示:&m.base == &m
base
custom_bar()
struct foo
struct foo
{
/* same as before ...*/
/* extra pointer. */
void * hook;
};
然后,修改接触演员表的东西,
void setup_meh ( struct meh * m )
{
m->base.hook = m;
/* set up function pointers as usual... */
}
void custom_bar ( struct foo * f, int a, int b )
{
struct meh * m = (struct meh*)f->hook;
/* override. */
}
这种技术更可靠,特别是如果您计划用 C++ 编写“派生结构”并使用虚函数。在这种情况下,第一个成员的偏移量通常为非 0,因为编译器将运行时类型信息和类的 v-table 存储在那里。
评论
void(*bar)(int, int);
void(*bar)(void *, int, int);
void*
struct foo
上一个:未找到 Java 类异常
评论
struct