static enumeration alternative

C

cppaddict

I would like to write, within the private section of my class
definition:

static enum TruncType {TRUNC_TOP,TRUNC_RIGHT,TRUNC_BOTTOM,TRUNC_LEFT};

but C++ does not allow this. The four values above are constant and
static, and will be used only by a private class method.

I could just do:

static const int TRUNC_TOP;
static const int TRUNC_RIGHT;
etc...

initializing them to distinct values in my .cpp file.

But it would be nicer to use an enum, or somehting else specifically
suited to this purpose. What is the best way to what I'm trying to
do? Ie, declare four static class constants whose values are
irrelevant except as distinguishing markers.

Thanks,
cpp
 
V

Victor Bazarov

cppaddict said:
I would like to write, within the private section of my class
definition:

static enum TruncType {TRUNC_TOP,TRUNC_RIGHT,TRUNC_BOTTOM,TRUNC_LEFT};

but C++ does not allow this. The four values above are constant and
static, and will be used only by a private class method.

If you drop 'static', then it should do what you need. If you place
that enumeration declaration in the private section, it should be
inaccessible to anybody but the class itself and its friends.
I could just do:

static const int TRUNC_TOP;
static const int TRUNC_RIGHT;
etc...

initializing them to distinct values in my .cpp file.

But it would be nicer to use an enum, or somehting else specifically
suited to this purpose. What is the best way to what I'm trying to
do? Ie, declare four static class constants whose values are
irrelevant except as distinguishing markers.

You're probably confusing enumerators and static data. Enumerators
are not static data. They are named constants.

Victor
 
C

cppaddict

You're probably confusing enumerators and static data. Enumerators
are not static data. They are named constants.

Right. But in this case I would like my named constants to be static.
There's no reason for each instance to have its own copy of them.
Other than that, an enumeration is perfect. So the decision is
between:

1. Use static named constants (bulkier syntax, but memory savings)

2. Use enum (cleaner syntax, but unnecessary duplicates)

What do you think?

Thanks,
cpp
 
K

Kai-Uwe Bux

cppaddict said:
Right. But in this case I would like my named constants to be static.
There's no reason for each instance to have its own copy of them.
Other than that, an enumeration is perfect. So the decision is
between:

1. Use static named constants (bulkier syntax, but memory savings)

2. Use enum (cleaner syntax, but unnecessary duplicates)

My understanding is that enum declarations declare *types* not *variables*.
No memory should be unsed for a type declaration.


Best

Kai-Uwe Bux
 
C

cppaddict

My understanding is that enum declarations declare *types* not *variables*.
No memory should be unsed for a type declaration.

But when an instance object is created, memory is allocated for each
of the TruncTypes. I think this must be the case, since enums can be
cast to int. In my example, there would be memory allocated for the
int's 0,1,2,3 for every object created. When in fact I only that
memory to be allocated once, since it can be shared among all the
objects.

I could be missing something, not sure....

cpp
 
V

Victor Bazarov

cppaddict said:
But when an instance object is created, memory is allocated for each
of the TruncTypes.

Who told you that? That's not true.
I think this must be the case, since enums can be
cast to int. In my example, there would be memory allocated for the
int's 0,1,2,3 for every object created. When in fact I only that
memory to be allocated once, since it can be shared among all the
objects.

I cant say I that sentence.
I could be missing something, not sure....

You're missing a whole lot, AFAICT.
 
K

Kai-Uwe Bux

cppaddict said:
But when an instance object is created, memory is allocated for each
of the TruncTypes.

Nope, memory is only allocated for the data fields of the object. The
declaration

enum TruncType {TRUNC_TOP,TRUNC_RIGHT,TRUNC_BOTTOM,TRUNC_LEFT}

tells the compiler to treat TRUNC_TOP as a name for some constant of type
TruncType, however this constant does not reside in memory. E.g., I think
you cannot take the address &TRUNC_TOP. Same as there is nothing like the
address of a specific int: &314.
I think this must be the case, since enums can be
cast to int.

That you can cast a value to int does not imply that value has to have an
address in memory.
In my example, there would be memory allocated for the
int's 0,1,2,3 for every object created.

Why would the compiler do that? The values 0,1,2,3 are known at compile
time. There is no need to store them at all. Your program certainly can use
the type unsigned long without some part of memory being used to store all
the values 0,1,2,3,4,5,6,7,8,...

Maybe it is most convincing, if you just try it out:

class X {
private:

enum whatever {
// make this as long as you can:
a,b,c,d,e,f,g,h,j,k,i,u,z,t,r,w
};

public:

whatever W;

};

#include <iostream>

int main ( void ) {
X x;
std::cout << sizeof( X ) << " " << sizeof( x ) << std::endl;
}

You will find that the only memory actually allocated is for the field W.


Best

Kai-Uwe Bux
 
C

cppaddict

But when an instance object is created, memory is allocated for each
Who told you that? That's not true.

It's based on the following reasoning; let me know where you think
it's flawed. Ater I create my object, my methods can refer to things
like TRUNC_TOP and TRUNC_BOTTOM, can they not? And they could cast
those values to an int, too. If there is no memory allocated for
them, where is that int coming from?
I cant say I that sentence.

The above should have read: "When in fact I only need that memory to
be allocated once." Sorry about that...

cpp
 
C

cppaddict

Maybe it is most convincing, if you just try it out:

class X {
private:

enum whatever {
// make this as long as you can:
a,b,c,d,e,f,g,h,j,k,i,u,z,t,r,w
};

public:

whatever W;

};

#include <iostream>

int main ( void ) {
X x;
std::cout << sizeof( X ) << " " << sizeof( x ) << std::endl;
}

You will find that the only memory actually allocated is for the field W.


Best

Kai-Uwe Bux

Kai-Uwe,

Thanks for that explanation. That cleared up a serious
minsunderstanding of mine. So I guess my reservations about using an
enum here were unfounded. I'm just going to use it...

Thanks again,
cpp
 
J

John Harrison

cppaddict said:
It's based on the following reasoning; let me know where you think
it's flawed. Ater I create my object, my methods can refer to things
like TRUNC_TOP and TRUNC_BOTTOM, can they not? And they could cast
those values to an int, too. If there is no memory allocated for
them, where is that int coming from?

It goes directly into the machine code generated.

int x = TRUNC_TOP;

Machine code (this is made up machine code)

mov sp[12], #1 ; move integer 1 into space reserved for variable x

You might as well as where the integer for this is

int x = 1;

it will be exactly the same machine code.

john
 
D

David Harmon

On Sat, 19 Jun 2004 03:50:03 GMT in comp.lang.c++, cppaddict
Ater I create my object, my methods can refer to things
like TRUNC_TOP and TRUNC_BOTTOM, can they not? And they could cast
those values to an int, too. If there is no memory allocated for
them, where is that int coming from?

The compiler pulls it out of the air. It comes from the same place 3
comes from in
if (i == 3) {

Note that it's illegal to write
int *i = &3;
because 3 has no address.
 

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

No members online now.

Forum statistics

Threads
474,171
Messages
2,570,935
Members
47,472
Latest member
KarissaBor

Latest Threads

Top