在运行时定义的C ++全局extern常量可用于多个源文件

时间:2014-09-27 07:05:30

标签: c++ c global-variables extern

我有一个在运行时定义的整数常量。此常量需要在全局和多个源文件中可用。我目前有以下简化情况:

  • ClassA.h 声明extern const int someConstant;

  • ClassA.cpp 在某些时候使用someConstant

  • Constants.h 声明extern const int someConstant;

  • main.cpp 包括 ClassA.h Constants.h ,声明{{1}在const int someConstant尝试在运行时将main()初始化为实际值的某个时刻。

这与someConstant常量完美无瑕地工作,我用它来使程序的名称在所有文件中全局可用,并且它的声明和定义与我试图在这里声明和定义的那个完全相同但是我无法让它与char *一起使用。

我首先在int处宣布该行error: uninitialized const ‘someConstant’ [-fpermissive],然后我得到main.cpp我认为是因为error: assignment of read-only variable ‘someConstant’默认初始化为。

有没有办法做我想在这里实现的目标?提前谢谢!


编辑(根据 @WhozCraig 的要求):相信我:它是不变的。我没有发布MCVE的原因是由于三个原因:这是一个任务,源是西班牙语,因为我真的想把问题保持为一般(并且可重复使用)。我开始写这个例子,中途它打击了我不是最清楚的问题。我会再试一次解释。

我被要求构建一个程序,该程序创建一个进程,反过来生成两个孩子(反过来会产生两个孩子,依此类推)。该程序将生成的代数视为单个参数。基本上创建一种二进制过程树。每个过程都必须提供有关他自己,他的父母,与原始过程的关系以及他的孩子(如果有的话)的信息。

因此,在上面的示例中, someConstant 实际上是一个包含有关进程信息的类(PID,PPID,子PID,与原始进程的关系程度等)。对于每个ClassA,我创建了这个类的新实例,因此我可以“保存”这些信息并将其打印在屏幕上。

当我定义与原始进程的关系时,我需要知道在调用程序时使用的参数,以检查此进程是否没有子进程(以更改该特定进程的输出) 。这是fork所需要的常数:要生成的世代数,树的“深度”。


编辑2 :我要道歉,这是漫长的一天,我没有直接思考。我将源代码从C切换到C ++只是为了使用一些OO功能而完全忘记了在 内部的 OO范例。我刚刚在解释这个问题时意识到我可以用我的类中的静态/类变量解决这个问题(用原始进程初始化),它可能不是常量(尽管语义上是这样)但是它应该可以工作,对吧?此外,我还意识到我可以用一些不可能的PID值初始化上一代的孩子,并用它来检查它是否是最后一代。


对不起伙计们,谢谢你们的帮助:看来问题是有效的,但一直都是错误的问题。新口头禅:走下电脑放松一下。

但是,回顾并保持观点,绝对不可能创建一个在运行时在C ++中定义的全局常量,如 @Jerry101 所说的那样?

5 个答案:

答案 0 :(得分:5)

在C / C ++中,const是在编译时定义的。它不能在运行时设置。

您可以在运行时设置const char *xyz;的原因是,它声明了一个指向const char的非const指针。棘手的语言。

因此,如果你想要一个可以在main()中确定并且之后没有改变的int,你可以编写一个getter int xyz(),它返回一个在main()或getter中初始化的静态值。 / p>

(顺便说一句,在多个头文件中声明相同的外部变量并不是一个好主意。)

答案 1 :(得分:2)

正如其他人所提到的,如果仅在运行时设置变量,那么变量远非常量。你不能“回到过去”并将程序执行过程中获得的值包含在程序构建之前。

您当然可以做的是定义您的程序的哪些组件对您的变量具有哪种访问权限(读取或写入)。

如果我是你,我会将全局变量转换为具有公共getter函数和私有setter函数的类的静态成员变量。声明需要将值设置为朋友的代码。

class SomeConstant
{
public:
    static int get()
    {
        return someConstant;
    }

private:
    friend int main(); // this should probably not be `main` in real code

    static void set(int value)
    {
        someConstant = value;
    } 

    static int someConstant = 0;
};

main

int main()
{
    SomeConstant::set(123);
}

其他地方:

void f()
{
    int i = SomeConstant::get();
}

你可以用一些语法糖来进一步隐藏这个类:

int someConstant()
{
    return SomeConstant::get();
} 

// ...

void f()
{
    int i = someConstant();
}

最后,添加一些错误检查以确保您注意到在设置之前尝试访问该值:

class SomeConstant
{
public:
    static int get()
    {
        assert(valueSet);
        return someConstant;
    }

private:
    friend int main(); // this should probably not be `main` in real code

    static void set(int value)
    {
        someConstant = value;
        valueSet = true;
    } 

    static bool valueSet = false;    
    static int someConstant = 0;
};

就编辑而言:

这与“OO”无关。面向对象的编程是关于虚函数的,我不知道你的问题是如何与虚函数相关的。

答案 2 :(得分:0)

char * - 表示创建指向char数据类型的指针。 int - 另一方面创建变量。你不能声明一个没有值的const变量,所以我建议你创建一个int *并用它来代替int。如果你将它传递给函数,则将其作为const

eg: int *myconstant=&xyz;
   ....  
   my_function(myconstant);
}
//function decleration
  void my_function(const int* myconst)
 {
    ....
 } 

答案 3 :(得分:0)

const 限定符表示变量必须在声明点中初始化。如果您在运行时尝试更改其值,则会获得UB。

答案 4 :(得分:0)

好吧,在C ++中使用const是为了让编译器在编译时知道变量的值,这样它就可以在遇到变量时执行值替换(很像#define但更好)。因此,除非使用extern进行显式声明,否则在定义时必须始终为const赋值。您可以使用本地int在运行时接收实际值,然后您可以使用该本地int值定义和初始化const int。

int l_int;
cout<<"Enter an int";
cin>>l_int;
const int constNum = l_int;