Re: Should accessors throw exception ?
On Sep 14, 3:48 pm, blargg....@gishpuppy.com (blargg) wrote:
In article <Xns9B18DCFE7997Fnobodyeb...@216.196.97.131>, Paavo
Helde<nob...@ebi.ee> wrote:
[...]
One design I have found handy:
T GetByName(const std::string name) const; // throws if name not found
T GetByName(const std::string name, T defaultvalue) const; // returns
defaultvalue if name not found
So the client code has the option to choose if it wants a
hard or soft fallback.
Nifty pattern, but wouldn't it tend to expand the interface
and bloat implementation if there were lots of functions like
this?
How many getters do you have in one class? In cases where you
systematically have something like this (e.g. data base access,
with null values in some columns), you would, of course, use a
class to represent nullable values; the above function would be
in that class, and the class representing a row would simply
return instances of that class.
I'd think returning something like boost::optional<T> that
throws when attempting to dereference when empty would be
best:
template<typename T>
checked_optional {
T t;
bool exists;
public:
checked_optional() : exists( false ) { }
checked_optional( T t ) : t( t ), exists( true ) { }
operator bool () const { return exists; }
T& operator * () const
{
if ( !exists )
throw "Bla bla";
return t;
}
};
checked_optional<T> GetByName( std::string name );
void use_t( T );
// Just dereference result if you want exception
use_t( *GetByName( "foo" ) );
But that doesn't solve the problem. At the client level, if you
want a default value, you have to declare an instance of a
variable, then test it. The whole point is to be able to
combine everything into a simple functional expression. (Also,
the use of implicit conversion to bool is blatant overload
abuse. If you want to check for validity, provide an isValid()
function.)
// Check the result before dereferencing if you want to handle not found
checked_optional<T> t = GetByName( "foo" );
if ( t )
use_t( *t );
else
not_found();
Wordy and obfuscated. And the interesting example would call
use_t with a default value if the value wasn't found, e.g.:
use_t( container.get( key ).elseDefaultTo( defaultValue ) ) ;
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34