使用指针函数模拟C结构中的成员函数

时间:2012-03-20 10:20:44

标签: c

所以只是为了“有趣”,我决定使用指针函数在C++中模拟C个成员函数。这是一个简单的代码:

obj.h:

#ifndef OBJ_H
#define OBJ_H

#include <stdlib.h>
#include <stdio.h>

struct Obj{
    struct pObjVar* pVar;

    void (*read)(struct Obj*);
    void (*set) (struct Obj*, int);
};

struct Obj* newObj();
void deleteObj(struct Obj** obj);

#endif

obj.c:

#include "obj.h"

void readValue(struct Obj* this_);
void setValue (struct Obj* this_, int mValue_);

struct pObjVar{
    int mValue;
};

struct Obj* newObj(){
    struct Obj* tmp  = (struct Obj*)     malloc(sizeof(struct Obj));
    tmp->pVar        = (struct pObjVar*) malloc(sizeof(struct pObjVar));

    tmp->pVar->mValue = 0;
    tmp->read = readValue;
    tmp->set  = setValue;

    return tmp;
}

void deleteObj(struct Obj **obj){
    free((*obj)->pVar); (*obj)->pVar = NULL;
    free((*obj)); *obj = NULL;
}

void readValue(struct Obj *this_){
    printf("Value = %d\n",this_->pVar->mValue);
}

void setValue(struct Obj *this_, int mValue_){
    this_->pVar->mValue = mValue_;
}

main.c中:

#include "obj.h"

int main(void)
{
    struct Obj* a = newObj();
    a->set(a, 10);
    a->read(a);
    deleteObj(&a);

    return 0;
}

输出:

>./a.out
 Value = 10    

然而,在这样做时,我认为我必须通过显式传递给我的成员函数来模拟隐式this指针的作用。我想这很好用,除了它让整个事情看起来很奇怪!

如果我想传递对象,为什么要将这些函数实现为成员函数?我发现它的唯一答案可能是你想要一个统一的界面,但各种实现? (某些类似C++虚函数?)

模仿成员函数的其他一些原因(如果有的话)是什么?另外,有没有办法绕过传递明确的this_指针?

编辑:传递对象时原始代码出现问题。我误将&a用于read/set函数。如果要在内部将指针设置为deleteObj,则只需要NULL

2 个答案:

答案 0 :(得分:3)

另一种写作方式:

#define member(FUNC, ...) FUNC(this_, ## __VA_ARGS__)
int reader(struct Obj *_this) {
  member(read, a, b, c);
  member(getch);
  return 0;
}

这可以用于实现接口,继承和许多C ++功能,这些功能在C with Classes次中实现。在Linux内核中,文件操作是这样实现的。文件结构存储指向函数的指针,以便每个文件系统都可以存储它自己的系统调用处理程序,这些处理程序在结构中的数据上运行。

答案 1 :(得分:1)

不,没有办法在C中自动执行此操作。标准预处理器无法胜任转换。

现在还有一种功能可以发现它被称为a->func(10)。在函数内部只有func(10)

当Bjarne Stroustrup开始设计C ++时,他为此编写了一个特殊的预处理器/编译器Cfront

实际上,C ++并不真正存储指向(非虚拟)函数的指针。它只是在编译代码时将a->set(10)转换为类似struct_Obj_set(a, 10)的内容。