How to implement simple class with variant field in c++ -
i want implement class let's have field key , class or b. argument in constructor in class array of chars. constructor pseudocode take @ first char, if exual 0x00 create class object, otherwise create class b object - both classes take array of chars argument.
anyway want keep implementation simple. don't want use boost::variant unless need to, , don't want implement sth implementing "variant" class because not familiar template programming , think problem can implemented in simpler way.
for pod types, have union
(but union won't remember which type assigned, store separately). won't work non-pod types. major reason because c++ doesn't know 1 should create upon construction / delete upon deletion of union.
but union can used hold pointers actual types. have care construction , deletion yourself.
you create this, wraps pointer-union , adds convenient interface. detailed explanation written in comments:
class eitheraorb { // have remember created: enum { a_type, b_type } m_which; // store either pointer or b. note union // stores 1 pointer reused interpret a*, b* or void*: union { *a; b *b; void *untyped; // accessing same pointer without looking @ type } m_ptr; // additional stuff want store besides , b const char *m_key; public: eitheraorb(const char *key) { // decision: type want create? m_which = key[0] == 0 ? a_type : b_type; // create type (the cast void* make pointer "untyped"): m_ptr.untyped = m_which == a_type ? (void*)new a() : (void*)new b(); // store additional stuff m_key = key; } ~eitheraorb() { // since stored actual contents outside , point them, // have free memory. this, have care // type again, correct destructor chosen. deleting // untyped pointer won't work here. if (m_which == a_type) delete m_ptr.a; if (m_which == b_type) delete m_ptr.b; } // these 2 functions can used query type stored. bool hasa() const { return m_which == a_type; } bool hasb() const { return m_which == b_type; } // these 2 functions can used query pointers actual types. // made them return null pointer if wrong getter used. *geta() { return m_which == a_type ? m_ptr.a : 0; } b *getb() { return m_which == b_type ? m_ptr.b : 0; } }
note implementation lack memory if copy instance of eitheraorb
. fix this, either disable copying (by making copy constructor , assignment operator private or disable them in c++11 using = delete
), or implement copy constructor , assignment operator copy pointee.
you said aren't familiar template programming. making implementation templated isn't difficult. put template<typename a, typename b>
before whole class definition; should work out of box. however, don't move implementations in .cpp
files in case; best keep them inlined wrote it.
then, a
, b
aren't types placeholders assign types in client code. i'd rename tempalte class either
, type names become either<this, that>
.
Comments
Post a Comment