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 union
is usually considered a bit low-level and unsafe for C++. As Pete Becker said, your union
-based solution should provide accessors instead of directly exposing the unsafe union
member. union
s also have the disadvantage that, prior to C++11, they can't contain non-POD data structures (so no std::string
).
An inheritance-based solution has the advantage that you can start using polymorphism (e.g., add a virtual PrintTo
method). (You can, of course, accomplish similar results by adding a PrintTo
method to a union
-based solution that does a switch
over TokenType
, but that's non-OO.)
A union
-based solution would probably be lighter-weight than an inheritance-based solution (no vtable
). 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.
Your class Token
implements what's known as a "discriminated union". But its members shouldn't be public; that makes it too easy to change the type stored in the union without updating the type flag. Instead, provide overloaded accessors to store and read values. The accessor that stores a bool
value should also set the type flag; similarly for the other accessors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With