I have some code which contains const
gobal variables; The code needs to be extended to support parametrization, ie, based on a parameter some of the variables have to change. It happens that some of the variables that need to change are global const
s.
file1.h
const double a = 2;
const double b = 3;
file.h is inherited by multiple different .cc
which use a
and b
.
After reading online I got introduced to the extern
keyword. So following some guidelines I did the following.
1) Declared a
and b
as externs
in the header file: file.h:
extern const double a;
extern const double b;
2) Created a file.cc
file where I use a function to assign values to a
and b
:
void setConsts(double parameter){
/* request the linkage */
extern const double a;
extern const double b;
if (parameter == 9){
a = 2 * 9;
b = 3 * 9;
}
else if (parameter == 10){
a = 2 * 10;
b = 3 * 10;
}
else{
std::cout<<"parameter not supported"<<std::endl;
Now probably because a
and b
are const
s I receive:
error: read-only variable is not assignable
What is the nice and the elegant way of changing global const
s into global variables which can be defined via a function, but still ensure that they will not be changed during run-time?
You cannot write to const
variables. That's the whole point of them being const
in the first place.
If you really need them to be non- const
, then remove the "const" keyword from them and recompile your application.
Note: using const_cast
will not work and will result in undefined behaviour (don't go there) since the objects are initially const. So don't even consider that (and btw a "C style cast" is also a const cast).
Step 1: Consider not using global variables. Instead pass values into the functions/classes that need them.
Step 2: Go to step 1 again.
Step 3: Ok, fine. If you really want globals... Try encapsulating them behind accessor functions. You could have something like GetGlobalA() and GetGlobalB() that all the code in your program can access. Then have an InitializeGlobals() which is obviously only used once during startup or wherever it is that these values need to be set. The variables themselves can simply be static ones inside a code file that nothing else has direct access to other than the functions I described (or if you make this all static on a class, then the variables are private statics of it).
If I understand you correctly, you want to initialize const
variable based on some parameter (either compile-time or run-time). Note that const
variables can be initialized by runtime expression.
double getParameter()
{
//obtain parameter and return it
return 9;
}
double getValueOfA(double param)
{
if (param==9)
return 2*9;
if (param==10)
return 2*10;
else{
throw(std::runtime_error("parameter value not supported"));
}
}
double getValueOfB(double param)
{
if (param==9)
return 3*9;
if (param==10)
return 3*10;
else{
throw(std::runtime_error("parameter value not supported"));
}
}
const double a=getValueOfA(getParameter());
const double b=getValueOfB(getParameter());
You cannot change the constants. If you want to set them from a parameter, constants are not what you are looking for. Once they are initialized, they cannot be changed.
I think that a good solution will be writing a simple class with privated variables a
and b
, with only getters to get them and a method to set them from a parameter. Then, add a global instance of this class and use it as you wish to. This way, user won't be able to change a
and b
directly, as they are privatized and you can decide, when user can set them and when he can't. As an example:
class optionsClass {
public:
optionsClass():parametersSet(false) {};
double getA(void) const {return a;}
double getB(void) const {return b;}
setParameter(double parameter) {
if(!parametersSet) {compute a and b here; parametersSet = true;}
}
private:
bool parametersSet; double a, b;
}
a
and b
in this example also couldn't be const, by the way. A standard constructor is called for these variables and they are autocratically set to 0.
Wrap your variables in a class and use constructor to init them. You can also use singleton and design only getter so that you can never change them.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.