【问题标题】:How to write virtual function in c? [closed]如何用c编写虚函数? [关闭]
【发布时间】:2017-05-25 16:27:18
【问题描述】:

为了遵循准备好的设计文档,我想在 C 中创建虚拟函数。是否有任何最佳实践可以做到这一点? 正如@imreal 建议的那样,我们可以使用函数指针来转换 C 结构,其工作方式类似于 C++ 类,但我们如何确保虚拟基类函数覆盖派生类函数。

在我的情况下,我需要此功能来遵循文档,但我认为当我们将 C++ 代码转换为 C 时,它也很有用。在将 C++ 代码与 C 代码结合时,这是必需的。

【问题讨论】:

  • C 中虚函数的用途是什么?
  • 您可以修改设计文件。
  • 用函数指针创建一个结构体,编写一个函数作为构造函数来为这些指针分配不同的函数。每个函数都需要一个 self/this 指针才能访问数据成员。
  • 你的意思是虚拟方法? C 没有方法;它甚至没有课程!
  • 使用object system(这就像回答“使用C++”但不同!)。如果没有对象系统,这个问题就没有任何意义——你发现赋予它意义的任何方式都意味着你定义了自己的对象系统,而不是使用现有的库或语言的系统。

标签: c virtual


【解决方案1】:

该语言不提供它作为一项功能,但您可以实现相同的功能。

用函数指针创建一个结构体:

typedef struct Base Base_t;
struct Base {
    void (*f1)(Base_t* self);
    void (*f2)(Base_t* self);

    int dat1;
    int dat2;
};

编写一个函数来充当构造函数,为这些指针分配不同的函数。

Base constructor1()
{
    Base l = {func1, func2, 0, 0};
    return l;
}

Base constructor2()
{
    Base l = {func3, func4, 6, 13};
    return l;
}

调用方法:

Base a = constructor1();
a.f1(&a);

每个函数都需要一个 self/this 指针才能访问数据成员。

活生生的例子:

http://ideone.com/LPSd65

【讨论】:

  • 使用更好的名称有利于提高可读性...
  • 此时,你为什么用C而不是C++?
  • @Donnie 有很多理由强制/更喜欢 C 而不是 C++ 并在 C 上模拟 OOP 是许多文章的主题,但我只是在回答 OP 的问题.
  • 这种方式如何重载基类函数?
  • @imreal - 我知道。我们也都这样做了,但值得提出这个问题,以便人们思考他们为什么选择他们正在选择的东西。我的措辞可能有点轻率。
【解决方案2】:

不,你不能。 'virtual' 不是 C 词汇表的一部分,'access level' 也不是

【讨论】:

  • C++ 是由 C 创建的,所以应该总是有一种方法可以在 C 中实现 C++ 功能。
  • @M.Khd,除非您建议对 C 编译器进行更改,否则这毫无意义。
  • @ikegami 我们可以将函数指针添加到结构中以创建类似于类的结构。所以也应该可以修改它们以创建虚函数。
  • @M.Khd,从未说过。当然,您可以编写与 C++ 程序具有相同效果的 C(或 Perl 或 VB)程序,当然您也可以近似这些语言中的一些 C++ 功能.但是你不能仅仅因为 C 是用 C++ 编写的,就给 C 提供这些特性。
  • @Henri 这取决于您是否要打印所谓的“kerstboom”;)
【解决方案3】:

在 C 中没有“虚拟”函数这样的概念。

相反,我建议您查看我的answer。

从根本上说:

  • 定义一个struct
  • 提供一套函数来执行struct
  • 如果特定用途需要不同的功能,则调用不同的函数

【讨论】:

  • 这如何为您提供虚函数的动态行为?
  • 它没有,因为这不是 C 语言中的东西。可以模拟它(如你的答案),但你最终会得到像 self->func(self, ...) 这样的东西,这会破坏可读性。
  • 仍然没有答案。
【解决方案4】:

没有内置语言支持,但如果缺少特殊实现,您可以获得与使用默认实现相同的一般功能。可能是这样的:

#include <stdio.h>

struct animal {
    const char *name;
    void (*move)(struct animal *);
};

void fly(struct animal *a)
{
    printf("soaring %s\n", a->name);
}

void walk(struct animal *a)
{
    printf("walk %s, walk\n", a->name);
}

void animal_move(struct animal *a)
{
    void (*move)(struct animal *) = a->move ? : walk;
    move(a);
}

int main(void)
{
    struct animal elephant = { .name = "elephant" };
    struct animal bird = { .name = "bird", .move = fly };

    animal_move(&elephant);
    animal_move(&bird);
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-03
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    相关资源
    最近更新 更多