C中的虚函数

时间:2011-07-27 12:43:26

标签: c

  

可能重复:
  How could one implement C++ virtual functions in C

在C ++中,类和结构之间的唯一区别是默认访问级别。因此,您可以在结构中使用虚函数,从结构继承等等。我的问题是,你能用C吗?

5 个答案:

答案 0 :(得分:10)

您可以使用存储在结构中的函数指针来执行“虚函数”。对于inheratince,你可以在另一个结构中嵌入一个结构,但语法将再次与你期望的不同。你可以用C编写面向对象的程序(经典的例子是unix文件/ socket / ... API),但语法非常笨拙。

此处的相关答案:https://stackoverflow.com/search?q=C+virtual+functions

答案 1 :(得分:5)

不,你不能。 'virtual'不是C词汇表的一部分,也不是'访问级别'

答案 2 :(得分:5)

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;
}

答案 3 :(得分:5)

您可以使用函数指针模拟虚函数。例如,

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库中的常见做法,包括jpegliblibpng。如果您对标准C I / O不满意,他们会使用这种技术来覆盖I / O程序。

编辑:正如评论中所述,这些代码中的一些依赖于(官方)非标准行为,这些行为“恰好”会在大多数编译器上运行。主要问题是代码假定&m.base == &m(例如base成员的偏移量为0)。如果不是这种情况,则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”。

答案 4 :(得分:3)

你做不到。 C结构不能有行为。他们只能拥有数据。

请参阅http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=tenBestQuestions C结构和C ++结构之间的差异。 它写在第二个问题中。

C ++结构与C ++类不同于C结构是不同的。这只是一个类比。

另外,在C中没有继承性这样的东西。没有继承性,你会用虚拟函数做什么?

相关问题