[英]Init values by using (somewhat) global variables vs. static function variables?
我在整个代码中都需要一些小辅助函数。 要工作,需要使用一些数据进行初始化。 我应该在哪里存储init数据?
我想出了两种方法:
我在helper.cpp文件的范围内创建静态变量,我使用专用的setter函数设置它,然后在我的帮助函数中使用。
static int _initData = 0;
void initHelpMe(int initData)
{
_initData = initData;
}
void helpMe()
{
doSomethingWith(_initData);
}
或者我在原始辅助函数中使用静态函数变量,并使用默认参数。
void helpMe(int initData = 0)
{
static int _initData = 0;
if (initData != 0)
_initData = initData;
doSomethingWith(_initData);
}
(假设0在initData的有效数据范围之外,并且我没有显示额外的代码,以确保首次调用该函数时引发错误而不首先启动它。)
这两种方法有哪些优点/缺点,是否有更好的方法呢?
我当然喜欢第二种方法,因为它将所有功能保存在一个地方。 但我已经知道它不是线程安全的(这不是一个问题atm)。
并且,为了使这更有趣,尽管是C ++,但这不是用于面向对象而是用于过程代码。 所以请不要提出建议对象或类的答案。 想象一下,它是C语言的C语言。
我打算建议你将数据包装到一个对象中,直到我意识到你要求一个带有C ++标签的C解决方案......
您的两种解决方案都有其优点。
第二个是我更喜欢的,假设我们只是“看起来像什么/可维护性”。 但是,如果使用initData == 0
多次调用helpMe
,则存在一个缺点,因为在第一种情况下不存在额外的if
。 如果doSomethingWith()
足够长的函数和/或编译器能够内联helpMe
(并且initData
是常量),这可能是也可能不是问题。
当然,代码中的某些东西也必须调用initHelpMe
,所以无论如何它可能会变成相同的。
总结:首选基于隔离/封装的第二个。
我显然更喜欢第二个! 不同编译单元中的全局静态数据以未指定的顺序初始化(尽管在一个单元中)。 首次调用时初始化函数的本地静态数据。
示例 :
如果你有两个转换单元A和B.单元A在初始化期间调用单元B的函数helpMe。假设初始化的顺序是A,B。第一个解决方案将零初始化_initData设置为某个initData。 之后,单元B的初始化将_initData重置为零,并可能产生内存泄漏或其他危害。
还有第三种解决方案:
void helpMe(int initData = 0)
{
static std::once_flag once;
static int _initData = 0;
std::call_once(once, [&] {
_initData = initData;
}
doSomethingWith(_initData);
}
我有两种感觉。
首选隔离选项2,但选项1适合移植到C ++类。 我已经编码了两种方式。 它归结为SW架构。
让我提出另一点。
两个选项都在下方:您没有将初始化限制为一次。 “需要用一些数据进行初始化”。 OP的条件似乎确保initHelpMe(123)
或HelpMe(123)
的正确初始化,然后是helpMe()
,但不要阻止/检测二次初始化。
如果需要防止/检测到辅助,则可以使用一些附加代码。
// Initialization
if (_initData != 0) {
; // Handle error
}
_initData = initData;
我使用的另一种范例如下。 它可能无法在您的代码中实现,因为它不会将initData
作为参数传递,但神奇地可以获得它。
void helpMe(void) {
static int Initialized = 0;
if (!Initialized) {
Initialized = 1;
_initData = initData();
}
doSomethingWith(_initData);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.