如何避免C中的“self”参数?

时间:2014-08-31 20:28:35

标签: c oop

我只是和C一起玩。这是我做的某种“阶级”:

typedef struct test{
    int x;
    int y;
    int(*mul)(test *);

} mult;

int testMul(test *t){
    return t->x * t->y;
}

mult newTest(int x_in, int y_in){
    mult tmp;
    tmp.x = x_in;
    tmp.y = y_in;
    tmp.mul = &testMul;
    return tmp;
}

如果我想使用mul()“方法”,我会这样做:

mult a = newTest(2,6);
a.mul(&a); //12

是否有一些聪明的方法可以避免&a参数,同时仍然可以访问mul()函数中的struct-Params?

3 个答案:

答案 0 :(得分:1)

可悲的是,没有干净方式来执行此操作,但您无法将引用传递给函数,因为函数是无状态

但你可以这样做,让它看起来更好:

(这是实施):

struct test {
    int x;
    int y;
};

test_t _test_create(int const x, int const y)
{
    test_t t = malloc(sizeof(* t));
    if (!t) return NULL;

    t->x = x;
    t->y = y;
    return t;
}

int _test_mul(test_t t)
{
    return t->x * t->y;
}

使用包含函数指针的全局变量:

(这是全球性的):

typedef struct test *test_t;

struct {
    test_t (*create)(int const x, int const y);
    int (*mul)(test_t t);
} test = { // <- also implementation (you don`t want to expose private function names)
    .create = _test_create,
    .mul    = _test_mul
};

然后你会这样称呼它:

test_t a = test.create(2, 6);

test.mul(a);

这样做的好处是,您始终可以看到a被引用的内容。但由于test指针表,它也消耗更多内存。

其他方面(提前警告宏):

#define test(obj, method, args...)    \
   (obj)->method(args)

test_t a = newTest(2, 6);
test(a, mul);

但这仅适用于指针。你需要非常小心。

答案 1 :(得分:1)

一种方法是定义辅助函数(以类名mult命名,方法名称mul):

int mult_mul(mult *x) { return x->mul(x); }

然后你会:

mult a = newTest(2,6);
mult_mul(&a));

这提供了多态行为,而不必重复对象名a。当然,对于其他方法,您可以向mult_xxx()函数添加其他参数。

答案 2 :(得分:0)

我通常会选择宏,例如

#define MUL(a) (a).mul(&(a))