简体   繁体   English

如何将全局const变量更改为可以通过函数分配的变量

[英]How change global const variables to variables that can be assigned via a function

I have some code which contains const gobal variables; 我有一些包含const gobal变量的代码; 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. 碰巧一些需要更改的变量是全局const

file1.h 文件1.h

const double a = 2;
const double b = 3;

file.h is inherited by multiple different .cc which use a and b . file.h被使用ab多个不同.cc继承。


After reading online I got introduced to the extern keyword. 在网上阅读后,我得到了extern关键字的介绍。 So following some guidelines I did the following. 因此,遵循一些准则,我做了以下工作。

1) Declared a and b as externs in the header file: file.h: 1)在头文件externs中将ab声明为externs:

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 : 2)创建了一个file.cc文件,在这里我使用一个函数来为ab赋值:

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: 现在可能是因为abconst所以我收到:

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? 将全局const更改为可以通过函数定义但不能在运行时更改的全局变量的好方法是什么?

You cannot write to const variables. 您不能写入const变量。 That's the whole point of them being const in the first place. 这就是它们首先是const的全部意义。

If you really need them to be non- const , then remove the "const" keyword from them and recompile your application. 如果确实需要它们为非const ,则从它们中删除“ const”关键字并重新编译您的应用程序。

Note: using const_cast will not work and will result in undefined behaviour (don't go there) since the objects are initially const. 注意:使用const_cast无法正常工作,并会导致不确定的行为(不要去那里),因为对象最初是常量。 So don't even consider that (and btw a "C style cast" is also a const cast). 因此,甚至不要考虑这一点(顺便说一句,“ C样式强制转换”也是const强制转换)。

Step 1: Consider not using global variables. 步骤1:考虑不使用全局变量。 Instead pass values into the functions/classes that need them. 而是将值传递给需要它们的函数/类。

Step 2: Go to step 1 again. 步骤2:再次转到步骤1。

Step 3: Ok, fine. 步骤3:好的,好的。 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. 您可能有类似GetGlobalA()和GetGlobalB()之类的东西,程序中的所有代码都可以访问。 Then have an InitializeGlobals() which is obviously only used once during startup or wherever it is that these values need to be set. 然后有一个InitializeGlobals(),它显然在启动期间或需要设置这些值的任何地方仅使用一次。 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). 如果我对您的理解正确,则希望基于某个参数(编译时或运行时)初始化const变量。 Note that const variables can be initialized by runtime expression. 注意, 可以通过运行时表达式来初始化const变量。

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. 我认为一个好的解决方案是编写一个带有私有变量ab的简单类,仅使用getter来获取它们,并使用从参数中对其进行设置的方法。 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. 这样,用户将无法直接更改ab ,因为它们已私有化,您可以决定何时设置用户以及何时不能设置。 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. 顺便说一句,本例中的ab也不能为const。 A standard constructor is called for these variables and they are autocratically set to 0. 将为这些变量调用标准构造函数,并将它们专心设置为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. 您也可以使用单例并且仅设计吸气剂,这样就永远无法更改它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM