C++ C++;开关中变量类型的确定 编辑:感谢您的回复。在开关上增加断路器;问题确实是,我希望能够在switch语句之后使用struct。
我希望能够做到以下几点:C++ C++;开关中变量类型的确定 编辑:感谢您的回复。在开关上增加断路器;问题确实是,我希望能够在switch语句之后使用struct。,c++,struct,C++,Struct,我希望能够做到以下几点: int foo (int type, void* inVar) { switch(type) { case 0: struct struct-type-one mystruct = *( (struct struct-type-one*) inVar); break; case 1: struct struct-type-two mystruct = *( (struct struct-ty
int foo (int type, void* inVar) {
switch(type) {
case 0:
struct struct-type-one mystruct = *( (struct struct-type-one*) inVar);
break;
case 1:
struct struct-type-two mystruct = *( (struct struct-type-two*) inVar);
break;
case 2:
struct struct-type-three mystruct = *( (struct struct-type-three*) inVar);
break;
}
// use mystruct.data
}
基本上,inVar
是指向结构的指针,type
告诉我们需要什么类型。结构都有数据,但结构的类型决定了数据的类型。我想这样做是因为在切换后的代码中,我们可以对mystruct.data
执行操作,而不必担心数据的实际类型
我的问题是,我们如何才能做到这一点?例如,在Python中这将是很容易的,但是C++不喜欢<代码> MyStult是“交叉初始化”,即可以根据开关语句的哪个分支使用不同的类型。模板化是我们一直在努力解决的一个想法,但这很困难,因为结构的名称不同,例如struct intStruct
,struct floatStruct
。这很重要,因为这些结构的大小取决于数据类型。有什么想法吗?你就快到了:
int foo (int type, void* inVar) {
switch(type) {
case 0: {
struct_type_1& mystruct = *static_cast<struct_type_1*>(inVar);
// use mystruct here
}
break;
case 1: {
// same thing again
}
}
}
intfoo(int类型,void*inVar){
开关(类型){
案例0:{
结构类型1和mystruct=*静态类型转换(因瓦);
//在这里使用mystruct
}
打破
案例1:{
//同样的事情
}
}
}
您最大的问题可能是没有在每个箱体周围使用支架。这意味着您的mystruct
变量发生冲突
要了解更多关于这类事情的信息,您可能需要查找的一个关键短语是“歧视性联盟”。另外,请查看Boost Variant以了解处理它的另一种方法。您可以使用类似以下内容:
int bar(Data& data);
int foo (int type, void* inVar) {
switch(type) {
case 0: return bar(static_cast<struct_type_0*>(inVar)->data);
case 1: return bar(static_cast<struct_type_1*>(inVar)->data);
case 2: return bar(static_cast<struct_type_2*>(inVar)->data);
}
return -1;
}
int-bar(数据和数据);
int foo(int类型,void*inVar){
开关(类型){
案例0:返回条(静态铸造(因瓦)->数据);
案例1:返回条(静态铸造(因瓦)->数据);
案例2:返回条(静态铸造(因瓦)->数据);
}
返回-1;
}
我不相信直接做你想做的事情是可能的(即使是这样,这也是C/C++中的一种反模式)。但是,如果您想使用mystruct.data
(而不是mystruct
本身),则可以通过以下方式重写代码:
int foo (int type, void* inVar) {
void* mystruct_data = NULL;
switch(type) {
case 0:
mystruct_data = ((struct struct-type-one*) inVar)->data;
break;
case 1:
mystruct_data = ((struct struct-type-two*) inVar)->data;
break;
case 2:
mystruct_data = ((struct struct-type-three*)inVar)->data;
break;
}
// use mystruct_data (and don't forget to check it's not NULL)
}
请注意,您需要先声明变量–您在switch()
中声明的内容仅限于该switch()
中
或者,如果您的数据处理依赖于类型
,则您可以执行以下操作:
int foo (int type, void* inVar) {
switch(type) {
case 0:
data_process_1((struct struct-type-one*) inVar);
break;
case 1:
data_process_2((struct struct-type-two*) inVar);
break;
case 2:
data_process_3((struct struct-type-three*) inVar);
break;
}
}
如果(正如标签所暗示的)你正在编写C++,你应该使用多态性或模板或其他简化语言的语言特征。p> 现在您所问的问题通常出现在遗留C代码中,因此对于这种语言,使用联合创建是很常见的,这就是您如何做到的(以下当然也是有效的C++):
让我们假设您有3种类型,如问题中所示struct Type1 {/*some implementation*/};
struct Type2 {/*some implementation*/};
struct Type3 {/*some implementation*/};
然后您将定义一个变量类型,如下所示
struct TVariant
{
int mtype;
union {
struct Type1 *m1;
struct Type2 *m2;
struct Type3 *m3;
};
};
并以这种方式利用它
int foo (int type, void* inVar)
{
struct TVariant v;
switch (type)
{
case TYPE_ONE:
v.mtype = 1;
v.m1 = (struct Type1*)inVar;
break;
case TYPE_TWO:
v.mtype = 2;
v.m2 = (struct Type2*)inVar;
// .... and so on
// .....
}
// Use your v, actually the correct member of the union in v
}
一些评论:
- 如果只针对一个函数,则不需要
的成员TVariant
,只需使用函数参数mtype
int type
,TYPE\u ONE
等是映射到类型TYPE\u TWO
,Type1
等的整数常量Type2
- 它比使用模板更麻烦,也更慢(由于信息丢弃和强制转换)
- 作为一个更简单的解决方案(对于c++),使用重载可以达到这个目的,因为每个不同版本的
对于每个foo
类型都有不同的实现
- 关于如何创建使用的变体对象,有多种变体李>
联盟,在C++中使用这种方法来实现C.的多态性,你有这样的缺点,所以不需要这些技巧。<李> - 最后也是最重要的,主要的缺点是,联合的大小将与其最大的成员类型相同,因此如果(如问题中所暗示的)您只想指向您的类型的指针,那么
,m1
,m2
应该是指针,并且联合的大小将始终具有单个指针的大小m3
- 最后也是最重要的,主要的缺点是,联合的大小将与其最大的成员类型相同,因此如果(如问题中所暗示的)您只想指向您的类型的指针,那么
break代码>在每个案例之后。另外,除非有必要,否则不要在C++中使用重新解释的情况。在这种情况下,只需使用dynamic_cast
。Bertrand Meyer选择让Eiffel语言没有enum
类型,很大程度上是为了避免在程序员面前进行上述愚蠢的类型切换(这是一种已知的反模式)。相反,要实现多态性,请使用多态性。C++支持静态和动态多态性,我怀疑后者使用虚拟成员函数,是您需要的。另一个极端问题是,您使用的是代码>空隙*/COD>,这意味着您丢弃了类型信息。这并不明智:反模式代码完全是关于“撤消”先前不必要的丢弃。只是不要放弃——使用类型。哦,在谷歌上搜索我发现了一个现成的教程:只是为了强调:虽然你可以在Python中这样做,但它也是Python中的反模式。不要写这样的代码。这里的问题是OP想在switch
子句之后使用mystruct
。那是不可能的。如果可能的话,我不知道怎么做,当然。但这正是OP想要的。我认为第二段代码足以解决这样的问题。代码的第二部分看起来与我所想的相似。然而,我试图避免编写三个不同的数据处理函数,因为它们都会做相同的事情,只是使用不同的类型。这肯定会奏效的!