如何在C中定义构造函数

时间:2011-06-01 17:21:23

标签: c haskell constructor

如何在C中创建Haskell / C ++样式构造函数?此外,一旦我有了这个新对象,我如何在其中定义操作(例如LinkedList / Tree)?

2 个答案:

答案 0 :(得分:17)

C对面向对象的概念(如构造函数)没有语言支持。

您可以按照以下方式手动实现:

typedef struct
{
    int field1;
    int field2;
} MyObject;

MyObject *MyObject_new(int field1, int field2)
{
    MyObject *p = malloc(sizeof(*p));
    if (p != NULL)
    {
        // "Initialise" fields
        p->field1 = field1;
        p->field2 = field2;
    }
    return p;
}

void MyObject_delete(MyObject *p)
{
    // Free other resources here too
    if (p != NULL)
    {
        free(p);
    }
}

void MyObject_doSomethingInteresting(const MyObject *p)
{
    printf("How interesting: %d\n", p->field1 * p->field2);
}

如果你想获得真正的高级,你可以使用可怕的复杂的宏和函数指针来模拟多态和各种类型(以类型安全为代价);见this book

另见this question

如果您对将面向对象的C ++编译为C感兴趣,请参阅this FAQ answer

答案 1 :(得分:4)

我怀疑@Oli Charlesworth的回答是你真正想要的,但为了完整起见,如果你真的想要 Haskell 式的构造函数:

  • TrueFalse等虚拟数据构造函数可以通过常规enum类型轻松表示。为了保持Haskell的准确性,您需要假装不能将它们视为整数值,除非您还假装您的Haskell类型是Enum的实例。

  • (True, "abc")这样的产品类型的数据构造函数可以由采用适当参数并返回适当struct的函数表示。 Haskell的“记录语法”可以使用struct来模仿,因为C样式的结构已经被Haskell的记录语法所模仿。是的,递归!

  • NothingJust 5等和类型的数据构造函数可以由union模仿。为了保持对Haskell的准确性,您需要“标记”联合以安全地区分案例,例如使用结构和枚举。可以将Haskell数据声明中的|视为指示未标记的并集,其中像NothingJust这样的构造函数是构造每个分支的产品类型的第一个元素所必需的构造函数。实现起来比实现起来要复杂得多,实现起来比起初听起来更简单。

  • 类型构造函数实际上并不能很好地转换为C.如果您愿意,可能会使用宏等来伪造它。但你可能不想,所以坚持单形代码。

如果您想在实际代码中实施上述任何一项,那么......祝你好运和上帝保佑。