2014-11-06 3 views
2

Буду признателен за вашу помощь!Внедрение гетерогенных массивов

Какая структура данных используется для реализации гетерогенного массива на C или C++? Массив может содержать любые стандартные типы данных, такие как int, float, char, string и т. Д.

+0

Я так понимаю, вы привыкли к другому языку. – Beta

+0

зависит !! возможно связанный список с указателем void на некоторую память, но, конечно, не 'array'. –

+0

@ Beta Что вы подразумеваете? Можете ли вы быть ясными? – leader

ответ

3

Как упоминает рави, соответствующая структура данных называется объединением тегов (также называемой вариантом записи). Один из способов его реализации заключается в следующем:

typedef union { 
    int tag; 
    struct { 
     int tag; 
     int val; 
    } int_; 
    struct { 
     int tag; 
     double val; 
    } double_; 
} object; 

Тогда вы можете создать массив из них.

object arr[5]; 

Вы используете tag поле, чтобы указать, какой член Союза в использовании. Обычно с enum.

enum type { INT, DOUBLE }; 

Затем установите метку при создании объекта и проверьте тег перед доступом. Это можно инкапсулировать, используя конструктор.

object new_int(int i){ 
    object ret; 
    ret.tag = INT; 
    ret.int_.val = i; 
    return ret; 
} 

object new_double(double d){ 
    object ret; 
    ret.tag = DOUBLE; 
    ret.double_.val = d; 
    return ret; 
} 

И вы обычно хотите использовать switch на бирке для доступа, написав другой случай для каждого типа.

void print_object(object x){ 
    switch(x.tag){ 
    case INT: printf("%d\n", x.int_.val); break; 
    case DOUBLE: printf("%f\n", x.double_.val); break; 
    } 
} 

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

for (i = 0; i < sizeof arr/sizeof*arr; i++) 
    if (arr[i].tag == INT) 
     arr[i] = new_double(arr[i].int_.val); 
1

В C++ такого массива нет, который может хранить элементы разных типов, а также нет контейнера в stl. Хотя есть один способ хранения другого элемента в контейнере, но условие - эти типы должны быть связаны через наследование.

В C существует концепция с названием tagged union, которая может хранить различные типы, давая тег как средство для указания какой переменной на самом деле существует.

Еще один способ сделать это - использовать массив указателей void *. Хотя это было бы довольно уродливым C++. Это не будет по-настоящему неоднородным, поскольку вы используете указатель типа, в который может быть введен любой указатель. Он похож на создание набора типа базового класса, а затем хранение объектов производных классов.

Это я из статьи Страуструпа: -

Если вам нужен гетерогенный контейнер в C++, определить общий интерфейс для всех элементов и сделать контейнер из них. Например:

class Io_obj { /* ... */ }; // the interface needed to take part in object I/O 

vector<Io_obj*> vio;  // if you want to manage the pointers directly 
vector< Handle<Io_obj> > v2; // if you want a "smart pointer" to handle the objects 

Помимо этого повышение :: Любые также могут быть использованы: -

vector<Any> v; 
+0

Пожалуйста, посмотрите [это] (http://www.boost.org/doc/libs/1_54_0/doc/html/any.html). Может ли он использоваться для реализации гетерогенного массива? – leader

+0

@leader: да, это будет прекрасно работать, чтобы перемещаться по «скрытым» типам, но поскольку вам нужно указать тип, чтобы получить данные из него, так как вам нужно будет выполнить любую операцию на нем. –

0

Я думаю, вы могли бы держать массив указателей на что

void* stuff[size]; 
const char* str = "hello"; 
int x = 20; 
int *array = malloc(sizeof(int) * 5); 
stuff[0] = str; 
stuff[1] = &x; 
stuff[2] = array; 

В качестве альтернативы, массив союзов, если вы знали все типы перед рукой.

+0

Как вы будете вводить данные в свою структуру данных? Вы можете объяснить? Я предполагаю, что вы будете использовать литье типов, и для этого нужно проверить тип данных перед правом? – leader

+0

Я добавил несколько примеров. Может оказаться полезным и массив структур, каждый с полем «тип» и «элемент void *». – ryanpattison

+0

filename.cpp \t [Ошибка] 'stuff' не называет тип – leader

Смежные вопросы