在C或C++中使用哪种数据结构来实现异构数组?数组可以包含任何标准数据类型,如int,float,char,string等。
qvtsj1bj1#
正如ravi提到的,适当的数据结构被称为标记联合(也称为 * 变量记录 *)。实现它的一种方法是:
typedef union { int tag; struct { int tag; int val; } int_; struct { int tag; double val; } double_; } object;
然后你可以把这些元素组成一个数组。
object arr[5];
您可以使用tag字段来指示哪个联合成员正在使用。通常使用enum。
tag
enum
enum type { INT, DOUBLE };
然后在创建对象时设置标记,并在访问之前检查标记。这可以通过使用 constructor 函数来封装。
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来访问,为每种类型编写不同的大小写。
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);
34gzjxbg2#
在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;
lztngnrs3#
我想你可以保存一个指向任何东西的指针数组
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;
或者,如果您事先知道所有类型,则可以使用联合数组。
3条答案
按热度按时间qvtsj1bj1#
正如ravi提到的,适当的数据结构被称为标记联合(也称为 * 变量记录 *)。实现它的一种方法是:
然后你可以把这些元素组成一个数组。
您可以使用
tag
字段来指示哪个联合成员正在使用。通常使用enum
。然后在创建对象时设置标记,并在访问之前检查标记。这可以通过使用 constructor 函数来封装。
你通常希望在标签上使用
switch
来访问,为每种类型编写不同的大小写。或者在某些情况下,您可能希望将数组折叠为单个类型,以便可以访问它而无需每次检查标记。
34gzjxbg2#
在c中没有这样的数组可以存储不同类型的元素,在stl中也没有容器。虽然有一种方法可以在容器中存储不同的元素,但条件是这些类型应该通过继承来关联。
在C语言中有一个叫做标记联合的概念,它可以存储不同的类型,给出标记作为一种手段来指定哪个变量实际存在。
另一种方法是使用void* 指针数组。虽然这将是相当丑陋的C。这不会是真正的异构,因为您使用的是一种任何指针都可以转换为的指针类型。它类似于创建基类类型的集合,然后存储派生类的对象。
这是我从Stroustrup的文章中得到的:
如果你在C++中需要一个异构容器,为所有元素定义一个公共接口,并为这些元素创建一个容器。举例来说:
除此之外,Boost::Any还可以用于:-
lztngnrs3#
我想你可以保存一个指向任何东西的指针数组
或者,如果您事先知道所有类型,则可以使用联合数组。