Initialized Constants

B

Brian C

Hello all,
I have a quick question coming from a long time C programmer, trying to
get back into C++. What I want to do is something like (C version):

int OpenLog(char *Filename)
{
FILE *stream;

if((stream=fopen(Filename,"w+"))==NULL)
return(ERROR);

fclose(stream);
return(OK);
}

Obviously this doesn't do much. The key lines are the two return()'s
that would have ERROR and OK defined in some "constants" header file.

In C++, I know you can create static functions that do not require you
to instantiate the class. However, is there a way to do this with
variables? I'd want to initialize them in the header file as well. So
far, all I've come up with is something like:

class Constants
{
public:
enum ReturnCodes
{
Error=-1,
Ok=0
};

....etc...
};

I can reference Constants::ReturnCodes::Error w/o instantiating the
class. Is there another way to do it?

Thanks.
 
V

Victor Bazarov

Brian said:
I have a quick question coming from a long time C programmer, trying
to get back into C++. What I want to do is something like (C version):

int OpenLog(char *Filename)
{
FILE *stream;

if((stream=fopen(Filename,"w+"))==NULL)
return(ERROR);

fclose(stream);
return(OK);
}

Obviously this doesn't do much. The key lines are the two return()'s
that would have ERROR and OK defined in some "constants" header file.

In C++, I know you can create static functions that do not require you
to instantiate the class. However, is there a way to do this with
variables? I'd want to initialize them in the header file as well. So
far, all I've come up with is something like:

class Constants
{
public:
enum ReturnCodes
{
Error=-1,
Ok=0
};

....etc...
};

I can reference Constants::ReturnCodes::Error w/o instantiating the
class. Is there another way to do it?

That's indeed a decent way of dealing with constants.

You can have separate static const ints in the same class. You can
replace 'class' with 'namespace' (and drop 'public' and the closing
semicolon), and then you don't need the keyword 'static':

namespace Constants {
{
enum ReturnCodes { Error = -1, Ok = 0 };
}

V
 
F

Frederick Gotham

Brian C posted:

class Constants
{
public:
enum ReturnCodes
{
Error=-1,
Ok=0
};

....etc...
};


If they're integer types, then you can initialise them within the class's
definition:


class Constants {
public:

static unsigned const magic_number = 42;

};


If they're something other than integer types, then you'll have to define
them in a source file as follows:


class Constants {
public:

static char * const address;

};

char * const Constants::address = 0; /* This line in source file */



Victor's idea of namespaces may also be viable.
 
G

Greg

Frederick said:
Brian C posted:




If they're integer types, then you can initialise them within the class's
definition:


class Constants {
public:

static unsigned const magic_number = 42;

};


If they're something other than integer types, then you'll have to define
them in a source file as follows:


class Constants {
public:

static char * const address;

};

char * const Constants::address = 0; /* This line in source file */

It is inconvenient to maintain both the declaration and the definition
of a single const variable in two separate places. So I would just
consolidate them both into one place - and not within a class but
within a namespace.

Note also that a const variable is, by default, static (that is, it has
internal linkage) - so the keyword static would be redundant for this
type of declaration. Here's an example:

namespace Constants
{
const double kPi = 3.14159265358979323846264338327950288;
}

Greg
 
B

Brian C

Frederick said:
Brian C posted:




If they're integer types, then you can initialise them within the class's
definition:


class Constants {
public:

static unsigned const magic_number = 42;

};


If they're something other than integer types, then you'll have to define
them in a source file as follows:


class Constants {
public:

static char * const address;

};

char * const Constants::address = 0; /* This line in source file */



Victor's idea of namespaces may also be viable.
Yes, I was playing with what Victor had suggested with the namespaces,
but I was using const static int's, which is kind of what you're
suggesting, and the compiler would not let me use them w/o instantiating
the class which is not what I wanted.

I do see the difference though with what I was trying w/ something like:

class Constants
{
public:
const static int Error = -1;
};

Seems you guys are putting static first. I'll have to check out the FAQ
because that is a quite annoying thing.

Thanks all.
 
F

Frederick Gotham

Brian C posted:

class Constants
{
public:
const static int Error = -1;
};

Seems you guys are putting static first. I'll have to check out the
FAQ because that is a quite annoying thing.


Freedom of expression: You can put the words in (pretty much) any order
you like.

The following two definitions are IDENTICAL:

int const a = 4;
const int a = 4;

as are the following two:

const char * const p = 0;
char const * const p = 0;

as are the following six:

const int static error = 5;
const static int error = 5;
int const static error = 5;
int static const error = 5;
static const int error = 5;
static int const error = 5;
 
A

Andrey Tarasevich

Brian said:
...
class Constants
{
public:
enum ReturnCodes
{
Error=-1,
Ok=0
};

....etc...
};

I can reference Constants::ReturnCodes::Error w/o instantiating the
class. Is there another way to do it?
...

Well, you probably know that already, but you can't really reference it
like that. The qualified name for the above 'Error' constant is
'Constants::Error', not 'Constants::ReturnCodes::Error'.
 
B

Brian C

Frederick said:
Brian C posted:




Freedom of expression: You can put the words in (pretty much) any order
you like.

The following two definitions are IDENTICAL:

int const a = 4;
const int a = 4;

as are the following two:

const char * const p = 0;
char const * const p = 0;

as are the following six:

const int static error = 5;
const static int error = 5;
int const static error = 5;
int static const error = 5;
static const int error = 5;
static int const error = 5;
Frederick,
Ok, I must've been confusing it with something else.

Thanks.
 
B

Brian C

Andrey said:
Well, you probably know that already, but you can't really reference it
like that. The qualified name for the above 'Error' constant is
'Constants::Error', not 'Constants::ReturnCodes::Error'.
Andrey,
Thanks. It does work however, I did notice that both worked, and I
wondered why. I'll have to try it under gcc, but VC++ lets you access it
either way.
 

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
473,774
Messages
2,569,599
Members
45,169
Latest member
ArturoOlne
Top