我在整个代码中都需要一些小辅助函数。 要工作,需要使用一些数据进行初始化。 我应该在哪里存储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的有效数据范围之外,并且我没有显示额外的代码,以确保首次调用该函数时引发错误而不首先启动它。)
这两种方法有哪些优点/缺点,是否有更好的方法呢?
我当然喜欢第二种方法,因为它将所有功能保存在一个地方。但我已经知道它不是线程安全的(这不是问题a.t.m。)。
并且,为了使这更有趣,尽管是C ++,但这不是用于面向对象而是用于程序代码。所以请不要提出建议对象或类的答案。想象一下,它是C语言的C语言。
答案 0 :(得分:1)
我打算建议你将数据包装到一个对象中,直到我意识到你要求一个带有C ++标签的C解决方案......
您的两种解决方案都有其优势。
第二个是我最喜欢的一个,假设我们只是过去看看/可维护性"。但是,如果使用helpMe
多次调用initData == 0
,则存在一个缺点,因为额外的if
在第一种情况下不存在。如果doSomethingWith()
足够长的函数和/或编译器能够内联helpMe
(并且initData
是常量),这可能是也可能不是问题。
当然,代码中的某些内容也必须调用initHelpMe
,因此无论如何它可能会变得相同。
总结:首选基于隔离/封装的第二个。
答案 1 :(得分:1)
我显然更喜欢第二个!不同编译单元中的全局静态数据以未指定的顺序初始化(尽管在一个单元中)。首次调用时初始化函数的本地静态数据。
示例强>:
如果你有两个翻译单元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 :(得分:0)
我有两种感觉。
首选隔离选项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);
}