在运行时定义的C ++全局外部常量可用于多个源文件
我有一个在运行时定义的整数常量。 此常量需要在全局和多个源文件中可用。 我目前有以下简化情况:
-
ClassA.h
声明了extern const int someConstant;
-
ClassA.cpp
在某些时候使用someConstant
。 -
Constants.h
声明了extern const int someConstant;
-
main.cpp
包括ClassA.h
和Constants.h
,声明const int someConstant
,并且在main()
期间的某个时刻尝试在运行时将someConstant
初始化为实数值。
这与一个char *
常量完美地工作,我使用它来使程序的名称在所有文件中全局可用,并且它的声明和定义与我试图在这里声明和定义的那个完全相同,但我无法得到它使用int
。
我得到第一个error: uninitialized const 'someConstant' [-fpermissive]
在我在main.cpp
声明它的行,后来我得到一个error: assignment of read-only variable 'someConstant'
我认为是error: assignment of read-only variable 'someConstant'
是因为someConstant
正在初始化默认值。
有没有办法做我想在这里实现的目标? 提前致谢!
编辑 (根据@WhozCraig的要求):相信我:它是不变的。 我没有发布MCVE的原因是由于三个原因:这是一个任务,源是西class牙语,因为我真的想把问题保持为一般(并且可重复使用)。 我开始写这个例子,中途它打击了我不是最清楚的问题。 我会再试一次解释。
我被要求构建一个程序来创建一个进程,该进程又生成两个孩子(这些孩子反过来会产生两个孩子,依此类推)。 该程序将生成的代数视为单个参数。 基本上创建一种二进制过程树。 每个过程都必须提供有关他自己,他的父母,与原始过程的关系以及他的孩子(如果有的话)的信息。
因此,在上面的示例中, ClassA
实际上是一个包含有关进程信息的类(PID,PPID,子PID,与原始进程的关系程度等)。 对于每个fork
我创建了这个类的新实例,因此我可以“保存”这些信息并将其打印在屏幕上。
当我定义与原始进程的关系时,我需要知道在调用程序时使用的参数,以检查此进程是否没有子进程(以更改该特定进程的输出)。 这是我需要的main
常数:产生的世代数,树的“深度”。
编辑2 :我将不得不道歉,这是漫长的一天,我没有直接思考。 我将源代码从C切换到C ++只是为了使用一些OOfunction而完全忘记了在OO范例内部思考。 我刚刚在解释这个问题时意识到我可以用我的类中的静态/类变量解决这个问题(用原始进程初始化),它可能不是常量(尽管语义上是这样)但是它应该可以工作,对吧? 此外,我还意识到我可以用一些不可能的PID值初始化上一代的孩子,并用它来检查它是否是最后一代。
对不起,伙计们,谢谢你们的帮助:看来问题是有效的,但一直都是错误的问题。 新口头禅:走下电脑放松一下。
但只是回顾并保持重点,绝对不可能创建一个在运行时用C ++定义的全局常量,就像@Jerry101所说的那样?
在C / C ++中,const是在编译时定义的。 它不能在运行时设置。
你可以设置const char *xyz;
在运行时,它声明了一个指向const char的非const指针。 棘手的语言。
因此,如果你想要一个可以在main()中确定并且之后没有更改的int xyz()
,你可以编写一个getter int xyz()
,它返回一个在main()或getter中初始化的静态值。
(顺便说一句,在多个头文件中声明相同的extern变量并不是一个好主意。)
正如其他人所提到的,如果仅在运行时设置变量,那么变量远非常量。 你不能“回到过去”并将程序执行过程中获得的值包含在程序构建之前。
当然,您仍然可以定义程序的哪些组件对变量具有哪种访问权限 (读取或写入)。
如果我是你,我会将全局变量转换为具有公共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”无关。 面向对象的编程是关于虚函数的,我不知道你的问题是如何与虚函数相关的。
char * – 表示创建指向char数据类型的指针。 int – 另一方面创建变量。 你不能声明一个没有值的const变量,所以我建议你创建一个int *并用它来代替int。 如果你将它传递给函数,则将其作为const
eg: int *myconstant=&xyz; .... my_function(myconstant); } //function decleration void my_function(const int* myconst) { .... }
const限定符表示变量必须在声明点初始化。 如果您尝试在运行时更改其值,则会获得UB。
好吧,在C ++中使用const是为了让编译器在编译时知道变量的值,这样它就可以在遇到变量时执行值替换(很像#define但更好)。 因此,除非使用extern进行显式声明,否则在定义时必须始终为const赋值。 您可以使用本地int在运行时接收实际值,然后您可以使用该本地int值定义和初始化const int。
int l_int; cout<<"Enter an int"; cin>>l_int; const int constNum = l_int;