Ö
Öö Tiib
On 12/28/2010 01:30 AM, Öö Tiib wrote:
On 12/27/2010 02:47 AM, Tiib wrote:
[...]
When i want uniform semantics for different types then i write a
family of function overloads. Something like bool IsMissing( T
const& ) that expresses such state.
But where do you store that information? Let's say you have a struct
like this.
struct MyData
{
std::string name;
std::string address;
int age;
double height;
int weight;
};
How would you distinguish missing, invalid, empty, etc. values in this
struct? And how would would you implement the signaling of those?
You think too much about data. You even name it as "Data". For me
behavior of object is way more important aspect than data. So for any
other object in system designed by me it is an interface exposed to
them and not a pile of data. Interface may be abstract and references
to all missing MyDatas in system may point at single immutable
MissingMyData that behaves in all situations like missing one should.
When it is so on case of MyData then it can be distinguished by memory
address:
bool IsMissing( MyData const& data )
{
return (&data ==&MissingMyData);
}
Hm, interesting. Do you define MissingMyData as a global constant?
Anyway, still, with this solution you force all MyData to be pointers,
right?All interfaces are anyway passed as pointers or references so that
solution should fit on lot of cases. MissingMyData can be immutable
constant in translation unit implementing MyData (and
IsMissing(MyData) or MyData::isMissing() ). Actual MissingMyData and
ExistingMyData are both derived from MyData interface.Modification of it is together with pimpl idiom where ImplMissing is
used as special private implementation for exceptional Missing state.
That one works on more cases, only that classes should be built then
using pimpl idiom. Objects in exceptional state may even externally
appear mutable since they may switch underlying implementations
dynamically.If it is good solution depends what behavioral flexibility is expected
from objects in exceptional state. If the object in Exceptional state
must be mutable during being in that exceptional state (rather rare
need) then you obviously need to instantiate such and can not use
single MissingMyData instance to incarnate them all. Exceptional
states can be built also as options into MyData class but that results
with if-else-polymorphism or switch-case-polymorphism that i consider
not that elegant.
Your solution is a good alternative. The only thing that seems
impossible in this whole discussion is to have a same solution for
non-pointer- and pointer types.
That does not bother me in general. When pointer does not point at
anything then it is NULL. I like to keep that like it is, so if it is
pointer that may be NULL then i am comparing it with NULL. That is
simple idiom and easy to see and understand i think. I mostly use such
with pointers to POD stuctures. Only thing is that it is sort of code
bloat to check for that nullness everywhere.
The code appears way more robust if NULLs are forbidden when you pass
polymorphic pointers (like for abstract interfaces) or envelope
objects (that use pimpl). Then there remain only contract checks about
nullness. Contract violation is programming error so you do not need
to find too graceful ways out of them.