I have a certain problem and I was stuck at which approach is better than the other:
A structure with an enum that defines the data in union member OR
A group of classes with inheritance
Sample code is given below:
Union based Structure
typedef union TokenValue{
bool bValue;
long lvalue;
double dvalue;
std::string svalue;
}
class Token{
public:
TokenType type;
TokenValue value;
};
Class Inheritance
class TokenBase{
public:
TokenType type;
};
class TokenNumber: public TokenBase{
public:
bool isInt;
long lvalue;
double dvalue;
};
class TokenString: public TokenBase{
public:
std::string svalue;
};
This type of design is known as a discriminated union or tagged union. You can Google for “C++ discriminated union” to see several examples of and approaches to this type of design.
A C
unionis usually considered a bit low-level and unsafe for C++. As Pete Becker said, yourunion-based solution should provide accessors instead of directly exposing the unsafeunionmember.unions also have the disadvantage that, prior to C++11, they can’t contain non-POD data structures (so nostd::string).An inheritance-based solution has the advantage that you can start using polymorphism (e.g., add a virtual
PrintTomethod). (You can, of course, accomplish similar results by adding aPrintTomethod to aunion-based solution that does aswitchoverTokenType, but that’s non-OO.)A
union-based solution would probably be lighter-weight than an inheritance-based solution (novtable). That might be preferable for something as low-level as lexer tokens.If third-party libraries are permitted, I’d strongly recommend taking a look at Boost.Variant for a more C++ approach to discriminated unions.