结构成员中的void指针和函数指针

时间:2011-02-14 12:23:31

标签: c

您好我有以下代码。

typedef struct __vector {
       int (*container_end) ( struct __vector *);
}vector;

和另一个具有以下声明的迭代器结构:

typedef struct __iterator {      
    void *ptr_to_container;  
    int (*end)(struct __iterator *);
}iterator;                          

int                                 
end(iterator *itr) {                
    return (itr->ptr_to_container)->container_end(itr->ptr_to_container);
}       

此代码无法编译,因为ptr_to_container是无效指针。

是否有解决此问题的方法。

container_end函数将单独定义,ptr_to_container将指向某个容器。

感谢 阿维纳什

4 个答案:

答案 0 :(得分:2)

在定义迭代器结构时,您似乎错过了一些东西。为什么迭代器有一个函数指针指向一个接受迭代器的'end'函数?

如果您希望它非常通用,您可以改为使用此定义:

typedef struct __iterator {
    void * ptr_to_container;
    int (*end)(void *);
} iterator;

int end(iterator * it) { return it->end(it->ptr_to_container)); }

在向量定义(和其他数据类型)中,您可以定义一个函数来创建迭代器:

static int vector_end(vector * v) { /* implementation omittted */ }

iterator * vector_create_iterator(vector * v)
{
    iterator * it = malloc(sizeof(iterator));
    it->ptr_to_container = v;
    it->end = vector_end;
    return it;
}

但是,解决方案实际上取决于数据结构的定义方式。在上面的建议中,由每个数据结构决定如何遍历它。

作为替代方案,您可以设置通用数据结构接口,例如

typedef struct _container container;

struct _container {
    int (*end)(container * c);
};

然后,矢量实现“只”必须填写此容器结构:

typedef struct _vector {
    container c;
    /* other fields required by the vector */
}

static int vector_end(container * c)
{
    vector * v = (vector *) c;
    ...
} 

container * create_vector()
{
    vector * v = malloc(sizeof(vector));
    v->c.end = vector_end;
    return v;
}

...迭代器可以只使用通用容器:

typedef struct _iterator {
    container * c; 
    /* other fields used by the iterator, such as current position */
}

int end(iterator * it) { return it->c->end(it->c); }

从问题中的代码示例中,看起来几乎就像你混淆了这两种方法: - )

答案 1 :(得分:0)

您是否尝试投射到矢量*?

return ((vector *)(itr->ptr_to_container))->containter_end(itr->ptr_to_container);

但是,你确定要这样做吗?您正在使用itr来调用函数,然后将itr传递给该函数。包含更多上下文(更多代码)会有所帮助。

答案 2 :(得分:0)

您需要将* ptr_to_container显式转换为向量指针:

((__vector *)(itr->ptr_to_container))->container_end

否则编译器不知道目标的结构是什么。

虽然,我真的不明白你为什么要这样的建筑。看起来你想在这里继承对象,但没有明确说明任何东西。它不会很好。在C中,您将不得不使用较少的通用结构,或转移到C ++。

答案 3 :(得分:0)

如果必须void *使用

int                                 
end(iterator *itr) {                
    return ((vector)(itr->ptr_to_container))->container_end(itr->ptr_to_container);
} 

或者在迭代器中指定它是一个向量迭代器

typedef struct __iterator {      
    vector *ptr_to_container;  
    int (*end)(struct __iterator *);
}iterator;  //probably you'll need to rename to make type of iterator clear

如果你需要保留抽象(所有容器的一个迭代器)没有想到的东西......