what is the best practice to store "modes": enum, int constant orwhat?

J

Jacek Dziedzic

Hi!

I often find that my programs need to store information on
"current mode of something" with two or at most several
mutually exclusive "modes" to choose from, e.g.

- datafile: is it in a) read-only mode or b) write-only mode,
- a function picking points a) above, b) below or c) contained
on a plane in 3D,
etc.

This "current mode" usually needs to be stored somewhere,
often also needs to be passed to a function. What is, from
the point of view of experienced programmers, the most
convenient way of expressing such modes?

Generally I can't decide between an enum and integer
constants, such as

// datafile open modes
const int mode_readonly=1;
const int mode_writeonly=2;

// direction selection for the pick_points() function
const int points_above=1;
const int points_below=2;
const int points_contained=3;

std::vector<xyz_triplet> pick_points(plane p, int mode) {
//...
}

Usually there are only two or three such modes for some
property, so I tend towards the "const int" version,
because somehow I'm convinced that creating an extra type
for such a thing is overkill, but perhaps I'm wrong?
Now the parameter "mode" usually needs some explanation
attached to it, because it isn't immediately obvious
what it means, as it is an int. On the other hand it seems
bad to me if my program is cluttered with a lot of types
like enum TPlaneMode {above,below,contained}.

Also, in what scope should such things be placed?
In my programs they usually wind up at the namespace scope,
so in a typical namespace I have a bunch of classes,
usually a few static variables a few of such constants.
Is it the correct way to go?

TIA,
- J.
 
I

Ian Collins

Jacek said:
Hi!

I often find that my programs need to store information on
"current mode of something" with two or at most several
mutually exclusive "modes" to choose from, e.g.

- datafile: is it in a) read-only mode or b) write-only mode,
- a function picking points a) above, b) below or c) contained
on a plane in 3D,
etc.

This "current mode" usually needs to be stored somewhere,
often also needs to be passed to a function. What is, from
the point of view of experienced programmers, the most
convenient way of expressing such modes?

Generally I can't decide between an enum and integer
constants, such as

// datafile open modes
const int mode_readonly=1;
const int mode_writeonly=2;

// direction selection for the pick_points() function
const int points_above=1;
const int points_below=2;
const int points_contained=3;

std::vector<xyz_triplet> pick_points(plane p, int mode) {
//...
}

Usually there are only two or three such modes for some
property, so I tend towards the "const int" version,
because somehow I'm convinced that creating an extra type
for such a thing is overkill, but perhaps I'm wrong?

Why is it an overkill? It comes with zero cost and several benefits.
Now the parameter "mode" usually needs some explanation
attached to it, because it isn't immediately obvious
what it means, as it is an int. On the other hand it seems
bad to me if my program is cluttered with a lot of types
like enum TPlaneMode {above,below,contained}.
Why? Give the enumerations explanatory names and you make your code a
lot clearer.
 
J

Jacek Dziedzic

Ian said:
Why is it an overkill? It comes with zero cost and several benefits.

I see.
Why? Give the enumerations explanatory names and you make your code a
lot clearer.

OK, I'll go for enums then. What about scoping? Should I leave
them at the namespace level?

thanks,
- J.
 
N

Noah Roberts

Jacek said:
Usually there are only two or three such modes for some
property, so I tend towards the "const int" version,
because somehow I'm convinced that creating an extra type
for such a thing is overkill, but perhaps I'm wrong?

Well, it depends. Is there a lot of stuff like:

switch (mode)
{
case MODEX:
... break;
case MODEY:
... break;
}


If so then you are probably a LOT better off making a new type and
using the state pattern, or possibly template method.

Even if not then you might be better off with a new type if it makes
your code clearer and/or breaks dependencies. You have to take each
situation as it arrives.
 
D

davidrubin

Jacek said:
Hi!

I often find that my programs need to store information on
"current mode of something" with two or at most several
mutually exclusive "modes" to choose from, e.g.

- datafile: is it in a) read-only mode or b) write-only mode,
- a function picking points a) above, b) below or c) contained
on a plane in 3D,
etc.

This "current mode" usually needs to be stored somewhere,
often also needs to be passed to a function. What is, from
the point of view of experienced programmers, the most
convenient way of expressing such modes?

Generally I can't decide between an enum and integer
constants, such as

// datafile open modes
const int mode_readonly=1;
const int mode_writeonly=2;

// direction selection for the pick_points() function
const int points_above=1;
const int points_below=2;
const int points_contained=3;

std::vector<xyz_triplet> pick_points(plane p, int mode) {
//...
}

Usually there are only two or three such modes for some
property, so I tend towards the "const int" version,

For a choice of two I would use 'bool'. For a choice of three, I would
use 'wide_bool'.
 
R

Richard Herring

Jacek Dziedzic said:
Hi!

I often find that my programs need to store information on
"current mode of something" with two or at most several
mutually exclusive "modes" to choose from,
[snip]

Generally I can't decide between an enum and integer
constants, such as

// datafile open modes
const int mode_readonly=1;
const int mode_writeonly=2;

// direction selection for the pick_points() function
const int points_above=1;
const int points_below=2;
const int points_contained=3;

std::vector<xyz_triplet> pick_points(plane p, int mode) {
//...
}

Usually there are only two or three such modes for some
property, so I tend towards the "const int" version,
because somehow I'm convinced that creating an extra type
for such a thing is overkill, but perhaps I'm wrong?

I think you're wrong. Having an extra type means increased type-safety:
the compiler will tell you if you try to pass an inappropriate mode as a
parameter. The compiler will also ensure your enumeration constants are
distinct, whereas if you accidentally typed "const int points_below=3;"
above, you're setting yourself up for a really obscure bug.
Now the parameter "mode" usually needs some explanation
attached to it, because it isn't immediately obvious
what it means, as it is an int.

If you use a well-named enum, the name of the type _is_ the
explanation. So it's self-documenting as well.
On the other hand it seems
bad to me if my program is cluttered with a lot of types
like enum TPlaneMode {above,below,contained}.

Saying what you mean, by having distinct types for distinct purposes,
and connecting the set of possible values directly to the type, is
usually considered a *good* thing. It helps those who have to maintain
the code, and also helps the compiler protect you from yourself.
Cluttering your program with a lot of (syntactically) unrelated
constants does neither.
Also, in what scope should such things be placed?
In my programs they usually wind up at the namespace scope,
so in a typical namespace I have a bunch of classes,
usually a few static variables a few of such constants.
Is it the correct way to go?
Depends. If the enumerated type only applies to a single class, you
could declare it inside the class.
 
J

Jacek Dziedzic

Richard said:
Jacek Dziedzic said:
Hi!

I often find that my programs need to store information on
"current mode of something" with two or at most several
mutually exclusive "modes" to choose from,

[snip]


Generally I can't decide between an enum and integer
constants, such as

// datafile open modes
const int mode_readonly=1;
const int mode_writeonly=2;

// direction selection for the pick_points() function
const int points_above=1;
const int points_below=2;
const int points_contained=3;

std::vector<xyz_triplet> pick_points(plane p, int mode) {
//...
}

Usually there are only two or three such modes for some
property, so I tend towards the "const int" version,
because somehow I'm convinced that creating an extra type
for such a thing is overkill, but perhaps I'm wrong?


I think you're wrong. Having an extra type means increased type-safety:
the compiler will tell you if you try to pass an inappropriate mode as a
parameter. The compiler will also ensure your enumeration constants are
distinct, whereas if you accidentally typed "const int points_below=3;"
above, you're setting yourself up for a really obscure bug.
Now the parameter "mode" usually needs some explanation
attached to it, because it isn't immediately obvious
what it means, as it is an int.


If you use a well-named enum, the name of the type _is_ the
explanation. So it's self-documenting as well.
On the other hand it seems
bad to me if my program is cluttered with a lot of types
like enum TPlaneMode {above,below,contained}.


Saying what you mean, by having distinct types for distinct purposes,
and connecting the set of possible values directly to the type, is
usually considered a *good* thing. It helps those who have to maintain
the code, and also helps the compiler protect you from yourself.
Cluttering your program with a lot of (syntactically) unrelated
constants does neither.
Also, in what scope should such things be placed?
In my programs they usually wind up at the namespace scope,
so in a typical namespace I have a bunch of classes,
usually a few static variables a few of such constants.
Is it the correct way to go?
Depends. If the enumerated type only applies to a single class, you
could declare it inside the class.

Thanks a lot to you and others who responded!

- J.
 
P

Phlip

Jacek said:
Thanks a lot to you and others who responded!

The best way to store modes is in some variation of the State Design
Pattern. You should have a pointer or reference to a parent class, with a
virtual method called "doMyMode()". Put the behavior specific to this mode
into derived classes, in their overrides of "doMyMode()".

This situation, sometimes called "replace conditional with polymorphism", is
the heart of OO design, and it will make your situation much more flexible
than an 'enum'. Regardless whether the enum itself is typesafe, you will
often scatter 'switch' statements around your code, based on the mode.
Replacing all these conditionals with a polymorphic type will make new types
easier to add.
 

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,733
Messages
2,569,440
Members
44,830
Latest member
ZADIva7383

Latest Threads

Top