异构数组实现

时间:2014-11-06 06:01:52

标签: c++ c arrays

感谢您的帮助!

在C或C ++中使用哪种数据结构来实现异构数组?该数组可以包含任何标准数据类型,如int,float,char,string等......

3 个答案:

答案 0 :(得分:4)

正如ravi所提到的,适当的数据结构称为标签联合(也称为变体记录)。实现它的一种方法是:

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 :(得分:1)

c ++中没有这样的数组可以存储不同类型的元素,也不存在stl中的容器。虽然有一种方法可以在容器中存储不同的元素,但条件是这些类型应该通过继承来关联。

在C中有一个称为标记联合的概念,它可以存储不同的类型,给出标记作为指定实际存在哪个变量的方法。

另一种方法是使用void *指针数组。虽然那将是非常难看的C ++。这不是真正的异构,因为你使用的是一种指针,任何指针都可以被强制转换。它类似于创建基类类型的集合,然后存储派生类的对象。

这是我从Stroustrup文章中得到的: -

如果您需要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

除了Boost :: Any之外,还可以使用: -

vector<Any> v;

答案 2 :(得分: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;

或者,如果您事先了解所有类型,那么就是一系列联盟。