2011-02-14 235 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 ...