Буду признателен за вашу помощь!Внедрение гетерогенных массивов
Какая структура данных используется для реализации гетерогенного массива на C или C++? Массив может содержать любые стандартные типы данных, такие как int, float, char, string и т. Д.
Буду признателен за вашу помощь!Внедрение гетерогенных массивов
Какая структура данных используется для реализации гетерогенного массива на C или C++? Массив может содержать любые стандартные типы данных, такие как int, float, char, string и т. Д.
Как упоминает рави, соответствующая структура данных называется объединением тегов (также называемой вариантом записи). Один из способов его реализации заключается в следующем:
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);
В 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;
Пожалуйста, посмотрите [это] (http://www.boost.org/doc/libs/1_54_0/doc/html/any.html). Может ли он использоваться для реализации гетерогенного массива? – leader
@leader: да, это будет прекрасно работать, чтобы перемещаться по «скрытым» типам, но поскольку вам нужно указать тип, чтобы получить данные из него, так как вам нужно будет выполнить любую операцию на нем. –
Я думаю, вы могли бы держать массив указателей на что
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;
В качестве альтернативы, массив союзов, если вы знали все типы перед рукой.
Как вы будете вводить данные в свою структуру данных? Вы можете объяснить? Я предполагаю, что вы будете использовать литье типов, и для этого нужно проверить тип данных перед правом? – leader
Я добавил несколько примеров. Может оказаться полезным и массив структур, каждый с полем «тип» и «элемент void *». – ryanpattison
filename.cpp \t [Ошибка] 'stuff' не называет тип – leader
Я так понимаю, вы привыкли к другому языку. – Beta
зависит !! возможно связанный список с указателем void на некоторую память, но, конечно, не 'array'. –
@ Beta Что вы подразумеваете? Можете ли вы быть ясными? – leader