动态访问联盟

时间:2017-12-17 21:21:16

标签: c++ struct enums unions

我有这个枚举,联合和结构:

union num {
    int i;
    short s;
    float f;
    double d;
};
enum tag {SHORT, INT, FLOAT, DOUBLE};
struct vrnumber {
    num num;
    tag type;
};

我想知道如何根据另一个变量(即用户的输入)动态访问union内的变量。 (即)我想用union的变量进行某个操作但是我想知道在运行时访问哪个union变量。那么什么是更好的方式而不是像:

vrnumber m; 
switch (m.type) {
    case SHORT: //an operation ..
    case INT: //same operation ...
    case FLOAT: //same operation ...
    case DOUBLE: //same operation ...
}

我认为这是非常冗长和多余的,而在每种情况下它都是相同的操作唯一的区别是当我访问联合存储或使用该值时。

1 个答案:

答案 0 :(得分:1)

执行此操作的方法是在结构定义中定义将要使用的运算符。例如,如果要使用运算符-,请定义以下方法:

struct vrnumber {
    num num;
    tag type;

    //between vrnumbers
    vrnumber operator- (const vrnumber& rhs);

    //vrnumbers and basic types
    vrnumber operator- (const int& rhs);
    vrnumber operator- (const double& rhs);

    //if vrnumber is used as rhs
    friend vrnumber operator- (const int& lhs, const vrnumber& rhs);
    friend vrnumber operator- (const double& lhs, const vrnumber& rhs);
};

以下是其中一些方法的定义示例:

vrnumber vrnumber::operator- (const vrnumber& rhs){
    switch(type){
        case SHORT:
            switch(rhs.type){
                //......
                //cases here
        }
        //......
        //cases here
    }
}
vrnumber vrnumber::operator- (const int& rhs){
    switch(type){
        case SHORT: return num.s-rhs;
        case INT: return num.i-rhs;
        case FLOAT: return num.f-rhs;
        case DOUBLE: return num.d-rhs;          
    }
}
vrnumber operator- (const int& lhs, const int& rhs){
    switch(rhs.type){
        //..........
        //...cases, same as the others
    }
}

以下是这些操作的一些示例:

vrnumber m1;
vrnumber m2;
int i1;
float f1;
//the example:
m1=f1-(m1-m2)-i1;

使用这种方法的权衡是冗长的运算符定义。但是,如果在代码中将此类操作称为 A LOT 次,则可能会缩短并简化代码。