2012-01-09 3 views
0

Как определить тип объекта в C? Моя цель это создать связанный список контейнер в С.Как получить тип объекта в коде?

Давайте предположим, что у меня есть функция, которая принимает указатель недействительным:

... 
Foo *f; 
f = Allocate(f); 
... 

void *Allocate(void *item) 
{ 
    return malloc(sizeof(f.GetType)); 
} 

Как сделать выше синтаксис возможно?

+0

1) Почему вам нужно знать тип для создания связанного списка? 2) Вы явно не хотите использовать C++? – dbrank0

ответ

2

Это невозможно. A void * указатель, это просто указатель на память, ничего больше, к нему больше не добавляется никакой информации. Невозможно выполнить то, что вы просите, вы не можете знать, сколько байтов должно быть malloc.

Вот почему, то qsort функция из библиотеки stdlib.h принимает в качестве параметра size в байтах каждого элемента массива. Если то, что вы предложили, было возможно, то qsort не нуждался бы в таком параметре.

Может быть, вы могли бы сделать что-то вроде этого:

... 
Foo *f; 
f = Allocate(f, sizeof(Foo)); 
... 

void *Allocate(void *item, size_t size) 
{ 
    return malloc(size); 
} 
2

В C, нет кросс-платформенный способ узнать базовый тип пустоты *, так как информация о типе не хранится в объекте. В C++ эта функция была добавлена ​​для объектов.

Вы можете, конечно, реализовать его самостоятельно для своих объектов, например, - хранения размера каждого объекта в самом объекте, но для системных объектов нет встроенного способа.

+0

Кстати, я работаю с Microsoft Compiler v9.0 (Visual Studio 2008), кросс-платформенный код не является приоритетом для моего проекта. –

+0

Учитывая работу, связанную с тегами и отслеживанием всех типов, для которых требуется приведенный выше синтаксис, я бы поискал другой способ сделать это. Обычный способ сделать это в C в вашем примере - это передать sizeof (Foo) вместо Allocate, поскольку вы знаете тип во время разговора. –

1

Это невозможно получить type с помощью void *. Если вы можете рассчитать размер Foo перед вызовом Allocate(), тогда получите размер и передайте его как параметр Allocate(), иначе вы должны сделать Foo, видимый внутри Allocate(), чтобы найти размер.

1

Единственный способ сделать это в C - создать свою собственную систему типов, в которой вы указываете типinfo для создаваемых вами типов. Это то, что было сделано, например, в Objective-C. В C все типы - это всего лишь серия байтов, когда вы выделяете память, которую вы выделяете только байты, то, что вы используете для этих байтов, не имеет отношения к компилятору C.

1

(спорная) красота C заключается в том, что она этого не делает. Указатель void - это просто адрес, который может указывать на что угодно. Вы могли бы создать свою собственную объектную систему (структуры с полем «тип» и поле «данные» - простой способ). Из вашей реализации также может быть вставлена ​​функция allocate в структуру Foo (при условии, что она есть), которая знает, как выделить себя (тип известен здесь).

1
void *Allocate(void *item) 
{ 
    return malloc(sizeof(f.GetType)); 
} 

Невозможно. Язык ISO C не предоставляет никаких возможностей для получения информации о типе через переменную. Расширения Gcc содержат оператор с именем 'typeof', он может получить информацию о типе с реального типа. такие как:

typeof (x[0](1)) 
int a; typeof (a) b; b = a; 

, но даже если типof также не смог получить информацию о реальном типе от указателя пустоты.приведенный ниже код не может быть скомпилирован успешно:

void *Allocate(typeof(*item) *item) 
{ 
    return malloc(sizeof(*item)); 
} 
Смежные вопросы