equivalent class to POD

C

cppquester

I got an app where a bunch of values are set before the calculation is
fired up.

I need an elegant way to check if all variables have been set.
So for example for double I am thinking
about a

class Double
{
private;
double val;
bool init;

public:
Double(): init(false) {}
Double( double v): val( v), init( true) {}

double Get() { if( !init) throw "Error"; return val;}
};

For calculations I might have to define many operators.

Apart from that: Into which trouble am I running?
As I am probably not the first to think about this basic issue,
is there already an implemtation for the basic POD available?

Thanks,
Marc
 
V

Victor Bazarov

I got an app where a bunch of values are set before the calculation is
fired up.

I need an elegant way to check if all variables have been set.

What does it mean for a variable to "be set"?
So for example for double I am thinking
about a

class Double
{
private;
double val;
bool init;

public:
Double(): init(false) {}

Why do you need this?
Double( double v): val( v), init( true) {}

If you only implement this, there is no need for the 'init' flag.
double Get() { if( !init) throw "Error"; return val;}
};

For calculations I might have to define many operators.

I am not sure this is relevant at all.
Apart from that: Into which trouble am I running?

I am not certain what the reason would be to provide a way to
*not* initialise an object which will throw an exception when
accessed *instead of* simply requiring for an object to always
be in a valid state by implementing only the constructor with
the argument.
As I am probably not the first to think about this basic issue,
is there already an implemtation for the basic POD available?

What for? PODs are a hack, necessary for C compatibility. Try
to see beyond them. Initialise all objects with proper values.
Then you will have no such problem.

V
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

I got an app where a bunch of values are set before the calculation is
fired up.

I need an elegant way to check if all variables have been set.

Write your code carefully and review it afterwards.
So for example for double I am thinking about a

class Double
{
private;
double val;
bool init;

public:
Double(): init(false) {}
Double( double v): val( v), init( true) {}

double Get() { if( !init) throw "Error"; return val;}
};

For calculations I might have to define many operators.

Apart from that: Into which trouble am I running?

You are probably not the first person to think of the idea to wrap built
in types in classes to provide additional error checking or function-
ality. If done correctly you should have little or no extra overhead
(except from the actual checks). However to do it right is quite a lot
of work, and while using templates will mitigate somewhat it is still
not a small task. If I were you I think twice about doing this unless
you plan to use it in a lot of places so that the extra development time
is small compared to the total development time.
As I am probably not the first to think about this basic issue,
is there already an implemtation for the basic POD available?

The best solution is probably to carefully review all code-paths to make
sure that you never operate on unset data. Then add asserts to make sure
of it.
 
C

cppquester

What does it mean for a variable to "be set"?

to be initialized. Set to some value.

Why do you need this?


If you only implement this, there is no need for the 'init' flag.





I am not sure this is relevant at all.

Double a(3.0), b(4.9);
Double c = a + b;
operator+ and operator=
would need to be defined.

I am not certain what the reason would be to provide a way to
*not* initialise an object which will throw an exception when
accessed *instead of* simply requiring for an object to always
be in a valid state by implementing only the constructor with
the argument.

It is a class with lots of parameters (memebers of type double).
These values need to be set by some setting member functions
(like e.g.:
void SetParam1( double value);
).
When the calculation is requested, I need a way to check if all
relevant parameters have been set.

As some of the parameters might take any value, just setting a default
value is not
sufficient.

In the setting member functions I could of course do some checking,
but for every
newly introduced parameter (extending the program) these functions
would need
to be adapted then (and result in a bool flag per parameter).

What for? PODs are a hack, necessary for C compatibility. Try
to see beyond them. Initialise all objects with proper values.
Then you will have no such problem.

The proper values are not known at construction time.

Another advantage of custom double replacement (class Double) would be
extensions like range checking. My example was just as simple as
possible.
 
M

Michael DOUBEZ

(e-mail address removed) a écrit :
I got an app where a bunch of values are set before the calculation is
fired up.

I need an elegant way to check if all variables have been set.
So for example for double I am thinking

Apart from that: Into which trouble am I running?
As I am probably not the first to think about this basic issue,
is there already an implemtation for the basic POD available?

An old method is to use dead value if available (nan for float, max for
int) at initialization and then assert them:
See
std::numeric_limits<>::quiet_NaN() or std::numeric_limits<>::infinity().
std::numeric_limits<>::max().


Michael
 
J

Jim Langston

to be initialized. Set to some value.



Double a(3.0), b(4.9);
Double c = a + b;
operator+ and operator=
would need to be defined.



It is a class with lots of parameters (memebers of type double).
These values need to be set by some setting member functions
(like e.g.:
void SetParam1( double value);
).
When the calculation is requested, I need a way to check if all
relevant parameters have been set.

As some of the parameters might take any value, just setting a default
value is not
sufficient.

In the setting member functions I could of course do some checking,
but for every
newly introduced parameter (extending the program) these functions
would need
to be adapted then (and result in a bool flag per parameter).

And if you have a bool flag per parameter, you have to remember to set the
bool flag for the constructor, assignment operator and copy constructor.
And since you have to remember to set the bool flag, you might as well
remember to set the variable itself. In other words, this gains you nothing
but a maintainance headache.
 
C

cppquester

In the setting member functions I could of course do some checking,
And if you have a bool flag per parameter, you have to remember to set the
bool flag for the constructor, assignment operator and copy constructor.
And since you have to remember to set the bool flag, you might as well
remember to set the variable itself. In other words, this gains you nothing
but a maintainance headache.

You mention three places! Three places instead of dozens of
parameters.
Which are set and later maybe reset.
This gains me a lot I guess.

It is even feasible that all paramteters insert pointers to themselfs
into some container,
making invalidation or serialization easy.

So still: Where is the drawback?
If there is one.
If not: Why is not such a thing readily available a boost.org or
similar?
 
V

Victor Bazarov

[..]
I am not certain what the reason would be to provide a way to
*not* initialise an object which will throw an exception when
accessed *instead of* simply requiring for an object to always
be in a valid state by implementing only the constructor with
the argument.

It is a class with lots of parameters (memebers of type double).
These values need to be set by some setting member functions
(like e.g.:
void SetParam1( double value);
).
When the calculation is requested, I need a way to check if all
relevant parameters have been set.

OK, so you're saying that for some operations only some members are
required, and for other operations other members are required to have
valid values, right? IOW, an object is allowed to have "part of it"
invalid if the operation does not require it.

That seems to require a flag for every operation (IOW, you would need
to either set all flags ahead of time by combining the validity of
the members in some manner, or set the validity flags and then every
operation will do the hard-coded check by combining the flags it knows
about, again in some manner). Too much work, and for what gain?
As some of the parameters might take any value, just setting a default
value is not
sufficient.

In the setting member functions I could of course do some checking,
but for every
newly introduced parameter (extending the program) these functions
would need
to be adapted then (and result in a bool flag per parameter).



The proper values are not known at construction time.

Then you might want to reconsider your model.
Another advantage of custom double replacement (class Double) would be
extensions like range checking.

That's not an extension, that's a limitation.
My example was just as simple as
possible.

It was most likely too simple.

I am guessing that even I can come up with a made-up example where not
all members would be "set" at the construction of an object and then
if an operation were to be performed, a check would be done and a green
light would be given if all needed parameters are set, and an exception
would be thrown otherwise.

I can even think of an example from the Standard library: a vector that
has N elements, N < M, can have new values inserted into, but cannot be
asked to supply any element with the index N..M-1, but this is not the
same, unfortunately. All member values _are_ set, they just don't meet
certain conditions. Same with, for example, a standard stream that was
read past the last element - the stream is in EOF condition - you can't
read from it, but you can close it. Again, all elements are set, but
not all operations can be performed (or lead to meaningful result).

Now, I imagine a car on the assembly line is closer. You can't really
sit inside [comfortably] until the seats are installed. You can't turn
it on until the engine is there. You can't move it independently until
the wheels have been attached, etc. But those contributing elements of
a car should then be probably modeled by pointers since nobody really
expects the car to be driven, or sat in, while the car is still on the
assembly line, and the only functionality it is expected to provide is
to be further assembled (completed). Individual tests could be still
performed (like turing on the lights to check connectivity). And the
system that performs those tests would of course (a) check if the system
to be test is present and reports (alleges) to be exercisable and (b)
that all exceptions are caught in the same scope where the test is
performed. IOW, the availability of the members that participate in
a certain operation is exposed to the object manager (and not limited
to the object itself so it could throw the exception when the operation
is attempted).

V
 
C

cppquester

(e-mail address removed) a écrit :




An old method is to use dead value if available (nan for float, max for
int) at initialization and then assert them:
See
std::numeric_limits<>::quiet_NaN() or std::numeric_limits<>::infinity().
std::numeric_limits<>::max().

Michael

I thought about this as well. It might be feasible but at least for
ints
it is rather unelegant, if all values might be valid (lets say at
least all
integral parameters together might very well cover the full range).
And for double or float NaN might be the result of some calculation as
well
(or can this never be quiet_NaN(), i.e. is quiet_NaN() especially made
for such a case ?)

However, I might fall back to this solution if it turns out that the
flagged
values (class Double) do have some drawbacks.
 
V

Victor Bazarov

I thought about this as well. It might be feasible but at least for
ints
it is rather unelegant, if all values might be valid (lets say at
least all
integral parameters together might very well cover the full range).
And for double or float NaN might be the result of some calculation as
well
(or can this never be quiet_NaN(), i.e. is quiet_NaN() especially made
for such a case ?)

Should it matter whether the value comes from some prior calculation or
from being "unset" -- it still cannot be used in the further operation,
can it? That would make the checking relatively simple, but the error
message should be different; not "value has not been set" but rather
"current value is not appropriate for the requested operation" (like the
domain error, e.g. negative values for calculating a logarithm of).
However, I might fall back to this solution if it turns out that the
flagged
values (class Double) do have some drawbacks.

At this point you should either make Double aware of all possible
operations so that each Double could say whether it is appropriate or
not. That is rather backwards if you intended to make Double simple
and efficient. For efficiency those flags need to be cached, and the
Double objects will be bloated with cached validity flags. Or you'll
need to sacrifice the granularity and freedom and define several
validity flags (or range flags) to be shared between some operations
(which is probably an acceptable compromise). In any way, you have
more designing to do, methinks.

V
 
C

cppquester

[..]
I am not certain what the reason would be to provide a way to
*not* initialise an object which will throw an exception when
accessed *instead of* simply requiring for an object to always
be in a valid state by implementing only the constructor with
the argument.
It is a class with lots of parameters (memebers of type double).
These values need to be set by some setting member functions
(like e.g.:
void SetParam1( double value);
).
When the calculation is requested, I need a way to check if all
relevant parameters have been set.

OK, so you're saying that for some operations only some members are
required, and for other operations other members are required to have
valid values, right? IOW, an object is allowed to have "part of it"
invalid if the operation does not require it.

That seems to require a flag for every operation (IOW, you would need
to either set all flags ahead of time by combining the validity of
the members in some manner, or set the validity flags and then every
operation will do the hard-coded check by combining the flags it knows
about, again in some manner). Too much work, and for what gain?

I provide the object which takes dozens of parameters.
Others will use my object.
As it is used in several environments, there are several member
functions
to set the needed parameters for convenience (in the different
environments
paramaters might be grouped differently).
In order to check if everything was properly initialized there would
be
a bunch of bool flags needed anyway (or using the elsewhere in this
thread mentioned
special (invalid) value approach).
But what if for a later extension another three paramters have to be
introduced?
Adding three bool flags.
All functions setting these new paramters would need to be modified.

Using a class wrapper for the POD seems to me way more elegant in this
situation.

I ask this here because I worried that I might restrict myself, i.e.
due to some
special rules for POD (which I oversee right now) there might be many
changes in the code necessary (implicit conversions not working
anymore, etc)
or some things are not working anymore (e.g. default initialization).

However, as far as I can see nonethelike was posted at least so far.
I considering to go with the class wrapper.

Thanks alot to all repliers!
Marc
 
S

Scott Gifford

I got an app where a bunch of values are set before the calculation is
fired up.

I need an elegant way to check if all variables have been set.

Just some ideas to think about: When I need to do this, I often use a
pointer to that object, which can be NULL if it is unset, or a default
flag value that doesn't otherwise make sense in the application, for
example INT_MAX for an application that should use fairly small
integers, or nan() for an application that should use a float/double
but shouldn't accept "not a number" as valid. C will sometimes extend
the type of a return value to make room for extra information, for
example get() returns an int instead of an unsigned char, so that -1
can mean "end-of-file"; I can't think of similar examples in standard
C++, but it should still be a usable technique.

Another thought: Java and C# call standard data types with object
semantics (including being settable to NULL) "boxed types". That
might be a useful keyword to search for.

As far as I can see, the technique you propose should work, but sounds
tedious.

Hope this helps,

-----Scott.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top