Listing 3: An example of Handle class use with a String class
#include <stdio.h> #include <string.h> #include <iostream.h> #include <vbtools/handle.h> class _String { public: typedef int Size; typedef char* Address; ~_String () { delete _text; } _String () : _text(0), _size(0) {} _String (Address, Size =0); Address text () { return _text; } Size size () { return _size; } void text (Address, Size); // private: Address _text; Size _size; }; _String::_String(Address addr, Size sz) : _text(0), _size(0) { text(addr, sz ? sz : addr ? strlen(addr) : 0); } void _String::text(Address addr, Size size) { delete _text; _text = (Address) memcpy(new char[_size = size], addr, size); } // String instances are of 'void*' size. Easy to pass around. // _String resources are handled automatically. typedef Handle<_String> String; HandleError string_is_empty; HandleError string_too_long; String foo(String input) { String s; if (!input->size()) { String err = String::error(string_is_empty); // A value can be set to error instance as well. err->text("Usage: foo argument.\n"); return err; } if (4 < input->size()) return s.error(string_too_long); s->text("Changed"); return s; } int main(int argc, char** argv) { String input(1 < argc ? argv[1] : (char*) 0); String orig = input; String output = foo(input); if (output.is_error()) { if (output.get_error() == string_is_empty) { // A value and an error condition can be // passed at the same time. cout << output->text() << endl; } else if (output.get_error() == string_too_long) { cout << "Argument is too long.\n"; } } else { cout << orig-> text() << endl; // argv[1] printed. cout << input->text() << endl; // "Changed" printed. } } //End of File