我经常需要编写包含 10 多个源文件的 c/c++ 程序,其中需要在所有文件中的函数之间共享少数变量。我之前读过,通常避免将全局变量与extern
. 但是,如果完全需要使用全局变量,此链接提供了一个很好的策略。最近,我一直在玩弄将所有变量包装在一个结构或一个类中并将这个结构传递给不同函数的策略。我想知道人们认为哪种方式更清洁,是否有更好的选择。
编辑:我意识到两种语言的策略可能不同。我对仅适用于一种语言或两种语言的策略感兴趣。
我经常需要编写包含 10 多个源文件的 c/c++ 程序,其中需要在所有文件中的函数之间共享少数变量。我之前读过,通常避免将全局变量与extern
. 但是,如果完全需要使用全局变量,此链接提供了一个很好的策略。最近,我一直在玩弄将所有变量包装在一个结构或一个类中并将这个结构传递给不同函数的策略。我想知道人们认为哪种方式更清洁,是否有更好的选择。
编辑:我意识到两种语言的策略可能不同。我对仅适用于一种语言或两种语言的策略感兴趣。
传递“上下文”数据的类/结构而不是全局变量。您会惊讶于全局变量变得不再全局的频率,不同的模块希望同时为其使用不同的值。
全局变量的更好替代方法是不使用全局变量。
不要试图使用结构或名称空间或单例或其他愚蠢的东西来掩盖它们,其唯一目的是隐藏您正在使用全局变量的事实。
只是永远不要创造一个。曾经。
它将迫使您考虑所有权和生命周期以及依赖关系和责任。你知道,成年人的事情。
然后,当您能够轻松编写全局自由代码时,您就可以开始违反所有这些规则了。
因为这就是规则的用途:被遵循,被打破。
This is the first question you should always ask, is this variable used GLOBALLY e.g. in all contexts. The answer is almost certainly... no it's not.
Is the variable global state, or is it context? Global state is usually rare, context on the other hand is quite common. If it's global state consider wrapping in a singleton so you can manage the how of interaction with your globals. Using Atomic<>
is probably not a bad idea, you should at least consider synchronization.
If it is context then it should be passed explicitly in a structure or class, as the data is explicitly relevant to that context an no-other. Passing context explicitly may seem like a burden but it makes it very clear where the context is coming from rather than just referencing random variables out of the ether.
It may seem odd to say that globals are scoped, but any global declared in a single file may be declared static
and thus unlinkable from any other file. This means you can restrict who has access to the global state in a given scope. This allows you to prevent people from randomly tweaking variables.
C++
无论如何,我发现使用namespace
. 这样您就可以消除 10 多个源文件之间的任何歧义。
例如:
namespace ObjectGlobalVars {
//Put all of your global variables here
int myvariable = 0;
}
//And then later on you can reference them like
ObjectGlobalVars::myvariable++;
在 c++
中,到处都是全局变量,这是错误代码的一个例子。
如果您想在全球范围内共享事物,请将它们分组并遵循单例模式。
例子:
class Singleton
{
private:
int mData;
public:
static Singleton& getInstance()
{
static Singleton instance;
return instance;
}
int GetData()
{
return mData;
}
private:
Singleton() {};
Singleton(Singleton const&);
void operator=(Singleton const&);
};
优点:
只有 1 个全局变量。我们单例的实例。
您可以在单例中包含互斥/信号量机制,以便对其成员进行线程安全访问。
- 限制其成员的访问,帮助您避免逻辑和同步缺陷。
缺点:
- 更难实施。- 如果你是第一次 -
在 c
中,您应该避免声明全局变量,而是在结构中传递它们。
例如:
struct MyData
{
int a;
int b;
};
void bar(struct MyData* data)
{
data->b = 2;
}
void foo()
{
struct MyData mdata;
mdata.a = 1;
bar( &mdata );
}
总而言之,在两种语言
中都应尽可能避免使用全局变量。