C++:实现一个全局常量,其值由用户给出

C++: implementing a global constant whose value is given by the user

首先,让我说一下,我已经阅读过类似的关于如何初始化全局变量或如何正确实现全局常量的线程。尽管如此,这些问题并没有真正帮助我解决我的具体问题,因为我也没有咨询过任何其他资源。问题如下。

我(必须)在头文件 header.h 中声明一个变量,该变量必须是常量并且由 main.cpp 中的主函数以及另一个文件中定义的其他函数使用 functions.cpp(之前在 header.h 中声明)。问题是这个常量是一个运行时常量,它的值是由用户给定的。我该如何进行?

我认为我最好的办法是执行以下操作。在header.h

// Header guard

namespace n
{
    // Some forward declarations

    extern const double mu; // The constant that should be initialized by the user.

    // Some other declarations
}

然后在 functions.cpp

#include "header.h"

namespace n
{
    // Some definitions here

    double function_that_uses_mu(double a, double b)
    {
        // Some code using mu

        return somedouble;
    }

    // Some other definitions
}

终于main.cpp

#include "header.h"
#include <iostream>

int main()
{
    // Some code

    double value_of_mu{};
    std::cin >> value_of_mu;        
    // Validity check
    extern const double n::mu{ value_of_mu };

    // More code

    return 0;
}

问题是由于error: ‘mu’ has both ‘extern’ and initializer导致编译失败。但是,如果我尝试 mu = value_of_mu 我显然会得到一个错误,因为我将分配给一个 const 值(而不是初始化它)。所以我不知道如何继续,或者我的代码有什么问题。我必须尊重两个强制性事实:

  1. Functions/global-consts 定义、functions/global-consts 声明和 main 必须在上述三个文件中分开。

  2. mu 将被定义为所有三个文件共享的常量。

这可能吗?怎么样?

编辑:

我认为我的问题是无法在函数内初始化扩展变量,但如果是这样,我不知道我是怎么做到的。

初始化变量时,不能指定extern。这应该可以代替:

int main()
{
    // Some code

    double value_of_mu{};
    std::cin >> value_of_mu;        
    // Validity check
    using namespace n;
    const double mu = value_of_mu;  // no extern specifier

    // More code

    return 0;
}

想一想:如果需要在程序的生命周期内设置一个值,那么它并不是真正的常量。因此,您不应该通过将其声明为 const 来假装它是一个常量。如果不想让程序不小心改变它的值,就得用其他方式保护它,比如让它成为class的私有成员变量。这样,您可以限制仅访问 return mu 的值作为常量。

// muholder.h

class muholder
{
 private:
    double m_value;
 public:
    muholder (double ivalue): m_value(ivalue) {}
    double const &value() const { return m_value; }
};

// workflow_envelope.h

class workflow_envelope
{
    private:
    muholder m_mu;

    public:
    workflow_envelope (double imu): m_mu(imu) {}
    bool validity_check();
    double method_that_uses_mu (double a, double b) const  { return a*m_mu.value()/ b; }
    void run(); // any "more code" goes in here. 
};

// main
#include "workflow_envelope.h"
#include <iostream>

int main()
{
    // Some code

    double value_of_mu;
    if (std::cin >> value_of_mu)
    {      
      // Validity check
      workflow_envelope workflow(value_of_mu);
      if (workflow.validity_check())
      {
         workflow.run();  
         return 0;
      }
    }
    return 1;
}