TITLE: a little initialization gem (Newsgroup: comp.lang.c++.moderated, 21 May 2000) GARDNER: Howard Gardner // Mostly when I post here, I'm asking questions. // And mostly I get good answers. So, by way // of saying thanks, here's a simple little class // that virtually eliminates "uninitialized variable" // bugs. It has saved me untold time over the last // few years, yet I haven't run across it anywhere. template class auto_init { public: typedef T value_type; private: value_type value; public: // This is the point of the exercise: provide a default constructor auto_init(void) :value(default_value) {} // These make it close to interchangeable with T auto_init(const auto_init & other) :value(other.value) {} explicit auto_init(value_type initial_value) :value(initial_value) {} auto_init & operator = (const auto_init & other) { value = other.value; return *this; } auto_init & operator = (value_type new_value) { value = new_value; return *this; } operator value_type (void) { return value; } // And these are useful sometimes value_type get(void) const { return value; } void set(value_type new_value) { value = new_value; } }; // You can do this for all the builtin types... typedef auto_init int_auto_init; #include void main(void) { using namespace std; // Most of the time, I can't tell the difference from the init'd type: int_auto_init a; int_auto_init b; a = 6; b = a; int_auto_init c (a*b + 100); int z = c - 29 + a; cout << "a = " << a << endl; cout << "b = " << b << endl; cout << "c = " << c << endl; cout << "z = " << z << endl; // But sometimes I can: int_auto_init x; // cin >> x; int_auto_init::value_type temp_x; cin >> temp_x; x.set(temp_x); cout << x << endl; } // It also saves having to write many default constructors, // which eliminates both the code and the bugs it would have // contained. class without_auto_init { int a; int b; int c; public: without_auto_init(void) :a(0), b(0), c(0) {} }; class with_auto_init { int_auto_init a; int_auto_init b; int_auto_init c; }; // I've actually experimented with many variations on this theme: // passing references (rather than values) in and out of the // functions, and building in a conversion so you can effectively // replace T's default constructor are a couple useful ones, but // this rendition can save you incredible amounts of time. I'd love // to find a way to make auto_init completely interchangeble with T. // And, of course, I'd love to see any little gems the rest of you are // holding onto. BARFURTH: Barfurth , 26 May 2000 This is most useful for declaring members of classes with multiple constructors (assuming most of these initialize the element to the same value). When you add/remove members or add/remove constructor overloads you can be sure the member will be initialized to a value that is meaningful (or at least has a predictable wrong value :o). Without such a class you have to manually keep in sync multiple initializer lists. HUBER: Heinz Huber > Wouldn't it be possible to overload operator >> for auto_init: > > template istream& operator >> (istream &is, auto_init ai) > { > T temp; > is >> temp; > ai = temp; > return is; > } [snip] GARDNER: 26 May 2000 Yes, that works for the extractor. Many similar cases will pop up, though: that line was meant to represent all of the annoying places where C++ isn't able to apply the cast automatically. It was meant as fair warning that this class is not an exact substitution for the init'd type, and it will irritate you at times. _______________________________________________ cpptips mailing list http://cpptips.hyperformix.com