C++ Constants

I want to create a static class that will hold constants.  Then I want to create another class that can get the value of static class constants.

Can anyone provide a code sample?

Thx
LVL 2
CipherISAsked:
Who is Participating?
 
evilrixSenior Software Engineer (Avast)Commented:
If it's just a class of static constants, just use a struct.

struct foo
{
   static const int bar = 10;
}

int main()
{
   return foo::bar;
}

Open in new window

0
 
Fabrice LambertFabrice LambertCommented:
Just make a structure with constant, or an enumeration .....
What's the point in encapsulating constants in a static class if you return them ? (if that even make a sens ...)

As for a class that will get values from a static class, I don't see a point either.

But well ..... if you really want to do it, take a look at the following:
#include <iostream>

class myStaticClass
{
private:
	static const int mConst = 5;
public:
	static const int getConst()
	{
		return mConst;
	}

};

class myClass
{
private:
public:
	const int getValue() const
	{
		return myStaticClass::getConst();
	}
};

int main()
{
	myClass cls;
	std::cout << cls.getValue() << std::endl;
	return 0;
}

Open in new window

0
 
phoffricCommented:
For a class having only static constants , then you don't need to have a private section and you don't need get functions . Just make everything public. You don't even need the class keyword . Instead you can just use struct which is like a class but by default, members are public.

Below comment from
https://www.experts-exchange.com/questions/25140107/constant-in-C.html

You may also want to have a static float or double constant.
In C++03 you could have a header file:
class A
{
public:
static float const f;
};

Open in new window

In the .cpp file, you define the floating object:
const float A::f = 10;

Open in new window

You can Reference the constant by simply using A::f .


Ref: "The C++ Programming Language, Special Edition" by Bjarne Stroustrup, Section 10.4.6.2 "Member Constants"

"It is also possible to initialize a static integral constant member by adding a constant-expression initializer to its member declaration."

In its example, it gives an example:
class Curious
{
public:
...
static const float c5 = 7.0; // error: in-class not integral
};

Open in new window


From this, it appears that it is simply a rule of the language. It is not clear to me why the C++ Language committee allowed a special dispensation for static const integral types, and forbid the same allowance for float types, another primitive type. Perhaps it was because then the question would be related to static const initialization of user defined types (and perhaps that would lead to other problems; so they drew the line at integral types). For simplicity, maybe there should not have been any dispensation at all, and just had one rule to cover all.

In his previous section 10.4.6.1 "Necessary Member Initialization", he says "For most types, the programmer has a choice between using an initializer and using an assignment. ... I usually prefer to use the member initializer syntax, thus making explicit the fact that initialization is being done." He then goes on to talk about efficiency advantage of using the initializer list (but that has been covered elsewhere amongst this discussion).
1
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 
phoffricCommented:
You may also want to declare a c++ constant user defined type. Here is a discussion on how to do that:
https://www.experts-exchange.com/questions/23035910/can-I-declare-a-c-constant-object.html
0
 
peprCommented:
I am not sure what is the real intention behind the question. You may be used to Java or C# where creating a static class for the purpose is necessary. In C++, you can create a "module" that contains only the constants. If you want to group them somehow, you can use namespace. If the situation is even simpler, you can define the constants in the form of a single header file with literals defined via the #define preprocesor macro.
0
 
Fabrice LambertFabrice LambertCommented:
Plus, I do not recommend making a class for the purpose of returning values from another one.

A class's purpose is to provide its own services, not the services of its neighbourg.
0
 
sarabandeCommented:
But well ..... if you really want to do it, take a look at the following:

myClass cls;  // not necessary

static member variables have the advantage that they could accessed without an object of the class.

//global.h
#ifndef GLOBAL_H
#define GLOBAL_H

class Global
{
    public:
         static const int MAX_ACCOUNTS = 10;
         static const char * GET_APP_TITLE() { return "MyApp"; }
         ....
};

#endif


//any.cpp
#include "global.h"
...

void Any::AnyFunction()
{
      std::string strAppTitle = Global::GET_APP_TITLE();
      for (int n = 0; n < Global::MAX_ACCOUNT; ++n)
      {
              ....
      }
}
...

Open in new window


note, i used a static (inline) function for the string literal to return because otherwise the static const char * member must be initialized in a cpp file and not in the header file to avoid creating duplicate symbols when the header was included by more than one cpp source. numerical literals and static functions can be defined (implemented) directly in the header.

generally, it makes sense to define constants within a class or struct or namespace to avoid lengthy and ambiguous names for the constants. if your constants are numeric, it is a proved method to defining enumeration types:

enum ELimits
{
      MAX_SUPPLIERS = 20,
      MAX_ACCOUNTS = 10,
      MAX_USER = 400
};

Open in new window


if you would put the above into global.h outside of the class Global,  the constants may be used from everywhere without prefix. the only condition is that global.h was included directly in the source or indirectly via another header.

you also could put the enumeration into class Global (or in a namespace 'SomeNameSpace') and use the constants for example like

   
int maxUser = Global::MAX_USER;

Open in new window


a special technique is used if you combine enumeration constants with strings (struct items):

class Location
{
       enum ELocation { HOME, BUREAU, VOYAGE, CUSTOMER, NUM_LOC };  
      
public:
       static const char * GET_LOC(ELocation loc) 
       { 
           static char * szLocs[NUM_LOC] = { "Home", "Bureau", "Voyage", "Customer" };
           return szLocs[loc]; 
       }
       ...

Open in new window


note, the constant NUM_LOC automatically "counts" the number of enum constants. in the sample HOME = 0, ..., CUSTOMER = 3 and NUM_LOC is 4.

Sara
0
 
Fabrice LambertFabrice LambertCommented:
We're pretty much all ending at the same point:
A structure or enumeration (enclosed in a namespace or not, it is your choice).

@Sara:
Better use std::string instead of char* IMO.
0
 
phoffricCommented:
>> just use a struct.
Yeah, that's what I said.
0
 
evilrixSenior Software Engineer (Avast)Commented:
Sorry, Paul. I missed that.
0
 
phoffricCommented:
Np. Actually thank you for reinforcing the idea and being more explicit with a piece of code.

I may actually get a chance to use C++11 in about a year. I thought I read that there is improvement in initializing static const float within a class. Is that right?
0
 
sarabandeCommented:
Better use std::string instead of char* IMO.
for a constant literal there is nothing as efficient than a  char or byte array. there is no advantage in using a std::string for code like i posted it, only overhead.

Sara
0
 
evilrixSenior Software Engineer (Avast)Commented:
>>Better use std::string instead of char* IMO
I agree with Sara for the reasons she's stated. If you're dealing with const literal strings there's really no reason to consume the expense of using std::string, which will most likely cost a heap allocation and incurs the unnecessary cost of including the string header where it may very well not be needed. Use std::string when it makes sense to do so. Here it doesn't.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.