【问题标题】:How change global const variables to variables that can be assigned via a function如何将全局 const 变量更改为可以通过函数分配的变量
【发布时间】:2016-08-13 15:51:32
【问题描述】:

我有一些包含const 全局变量的代码;代码需要扩展以支持参数化,即基于参数,一些变量必须改变。恰好有些需要更改的变量是全局的consts。

file1.h

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

file.h 由多个不同的.cc 继承,它们使用ab


在线阅读后,我了解到extern 关键字。所以按照一些指导方针,我做了以下事情。

1) 在头文件中将ab 声明为externsfile.h:

extern const double a;
extern const double 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;

现在可能是因为 abconsts 我收到了:

错误:只读变量不可赋值


将全局consts 更改为可以通过函数定义的全局变量,但仍确保它们在运行时不会被更改的好方法是什么?

【问题讨论】:

    标签: c++ c++11 global-variables constants extern


    【解决方案1】:

    您不能写入const 变量。这就是他们首先成为const 的全部意义所在。

    如果您确实需要它们为非const,则从它们中删除“const”关键字并重新编译您的应用程序。

    注意:使用const_cast起作用,并且会导致未定义的行为(不要去那里),因为对象最初是 const。所以甚至不要考虑这一点(顺便说一句,“C 风格转换”也是 const 转换)。

    【讨论】:

      【解决方案2】:

      第 1 步:考虑不使用全局变量。而是将值传递给需要它们的函数/类。

      第 2 步:再次转到第 1 步。

      第 3 步:好的,好的。如果您真的想要全局变量...尝试将它们封装在访问器函数后面。您可以拥有程序中的所有代码都可以访问的 GetGlobalA() 和 GetGlobalB() 之类的东西。然后有一个 InitializeGlobals() 显然只在启动期间或需要设置这些值的任何地方使用一次。变量本身可以只是代码文件中的静态变量,除了我描述的函数之外,没有其他任何东西可以直接访问(或者如果你在一个类上将它们全部设为静态,那么变量就是它的私有静态)。

      【讨论】:

        【解决方案3】:

        如果我理解正确,您想根据某个参数(编译时或运行时)初始化 const 变量。请注意,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());
        

        【讨论】:

          【解决方案4】:

          将变量包装在一个类中并使用构造函数来初始化它们。您还可以使用单例并仅设计 getter,这样您就永远无法更改它们。

          【讨论】:

            【解决方案5】:

            您无法更改常量。如果您想从参数中设置它们,则常量不是您正在寻找的。一旦初始化,就无法更改。

            我认为一个好的解决方案是编写一个带有私有变量ab 的简单类,只有获取它们的getter 和一个从参数设置它们的方法。然后,添加此类的全局实例并根据需要使用它。这样,用户将无法直接更改ab,因为它们是私有化的,您可以决定用户何时可以设置以及何时不能设置。举个例子:

            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;
            }
            

            ab 在这个例子中也不能是 const,顺便说一下。为这些变量调用标准构造函数,并将它们自动设置为 0。

            【讨论】:

            • 您不能更改常量。它们的值是在编译过程中计算的,而不是在运行时”这是constexpr 变量,而不是const。考虑一下:const int a=getInt(); int getInt(){int a;scanf("%d',a);return a}
            • @PcAF 我的错,对不起。反正constconstexpr都不适合提问者的情况。
            猜你喜欢
            • 2017-01-23
            • 2019-10-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多