2011-02-14 161 views
1

您好,我有以下代码。结构成员中的void指针和函数指针

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将指向某个容器。

感谢 阿维纳什

+0

你有没有尝试铸造itr-> ptr_to_container为`__vector *`? – 2011-02-14 12:26:58

+1

[__vector作为标识符是未定义的行为](http://stackoverflow.com/questions/224397/why-do-people-use-double-underscore-so-much-in-c),我知道几个编译器实际上也会窒息。 [另见](http://c-faq.com/decl/namespace.html) – Flexo 2011-02-14 12:38:38

回答

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); } 

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

0

你尝试强制转换为矢量*?

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

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

0

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

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

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

虽然我真的不明白你为什么要这样的建设。看起来你想在这里继承对象,但没有明确指出任何东西。它将无法正常工作。在C中,你必须使用较少的通用结构,或者转向C++。

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 

如果你需要保持抽象(一个迭代器对所有的你容器)没有想到atm ...