royop@tb- said:
Hello:
i have a function that reads a file as an argument and returns a reference
to an object that contains some information obtained from the file: FData
&ReadFile(string FilePath);
But , for example, when the file doesnt exists, i should not return any
reference to a bad constructed object, so i need something as a NULL
reference object. I suppose i could return a pointer instead, but i have
some code written with references which I´d like to preserve...
You have a number of choices. First of all, I have to wonder why you're
returning a reference at all -- almost the only time you want a function
to return a reference is when it's returning a reference to an object
that was passed to it as a parameter (e.g. operator= return *this, or
operator<< or operator>> returning a reference to the stream in which it
was invoked).
If you insist on doing this anyway, one possibility is to create a
static instance of an object and return a reference to it when you need
a null object:
class FData {
public:
static FData null_object;
// ...
};
FData::null_object;
FData &ReadFile(string const &FilePath) {
// I know access isn't portable, but hopefully I can get away with it as
// filling, so to speak.
if ( !access(FilePath.c_str(), 0))
return FData::null_object;
// ...
}
Using this implicitly assumes that the object in question is relatively
small -- if an object takes up a lots of space, you probably don't want
to create one just to use as a null object. This allows you to use
references, but having introduced the possibility of a null object being
returned, your code usually has to be written a lot like if you used
pointers -- instead of 'if ( returned_value == NULL)', you use something
like 'if (&returned_value == &FData::null_object)', but the basic form
of the code becomes almost like you used pointers.
You've already mentioned the possibility of using pointers, and (more or
less) rejected it.
Another possibility would be for ReadData to throw an exception if it
can't do what it's been asked to. Normally I wouldn't suggest this for
dealing with a situation like a missing file, but if it allows you to
write the rest of your code a lot more cleanly, it may be justified.