全局变量,它们到底是什么
Global variables, what are they exactly?
首先,我是c++的新手,正在"尝试"给变量加前缀。但我不是很清楚。所以我的问题是,它是正确的前缀静态变量与"g_"?谢谢你!
using namespace std;
// The main window class name.
static TCHAR g_szWindowClass[] = _T("win32app");
// The string that appears in the application's title bar.
static TCHAR g_szTitle[] = _T("Win32 App");
...
最好使用前缀来区分全局变量。但
-
最好尽可能避免全局变量,
-
代替C风格的前缀,在c++中你可以使用命名的命名空间
它也有很多优点,以避免微软的T
宏愚蠢。它支持Windows 9x,你可能不瞄准Windows 9x。而且,它有很多优点,不仅仅是维护,避免了微软愚蠢的匈牙利符号的事情,即像sz
这样的前缀,这是支持微软1980年代的程序员工作台帮助系统,这就像Windows 98一样不再是非常相关的。
同时,在实际可能的情况下使用const
也是有利的。
注意,名称空间级别的const
意味着静态存储类,因此不再需要显式的static
。
因此,代替当前的
// The main window class name.
static TCHAR g_szWindowClass[] = _T("win32app");
namespace g {
auto const windowClassName = L"win32app";
}
c++命名空间
g
代替C前缀g_
, 新增const
,保证该变量不被修改,直接使用宽字符字面量代替Microsoft Windows 9x
T
宏
那么您可以引用g::windowClassName
,或者在using namespace g;
之后不使用前缀,甚至可以使用g
的别名。
我对命名空间使用的特殊大括号约定是为了支持嵌套的命名空间,而没有缩进的麻烦。不幸的是,普通编辑器不支持这种功能。
c++没有正式的命名约定。对于变量名或一般的标识符,它确实有一些规则,您必须遵循这些规则,但除此之外,名称完全取决于您,以及它带来的所有灵活性和危险(非常像语言的其他部分)。
下面是一个很好的规则概述:http://en.cppreference.com/w/cpp/keyword
所以,例如,_G_szTitle
是错误的,但g_szTitle
是可以的。
真正的问题是你几乎肯定不想使用全局变量。全局变量几乎总是坏设计。避免它们。
另一个较小的问题是你使用了所谓的"匈牙利符号"。谷歌一下,找出为什么很多人(包括我自己)反对它,特别是在像c++这样的语言中。
全局变量最明显的定义是在命名空间范围内声明的变量(包括最外层的命名空间)。
现在,您可能认为在命名空间作用域中声明的变量也声明为static
,因此在给定的翻译单元之外不可见。同样,在未命名的名称空间中声明的变量可能被认为是非全局的。然而,这两种类型的变量都具有全局变量的许多不好的属性。例如,当从多个线程访问时,它们引入了一个序列化点。
因此,我认为实际上更广泛的变量是全局的,也就是类中的static
数据成员和函数区域static
变量。每一个在一个程序中也只存在一次。仅仅因为这些结构碰巧用于一些[反]设计模式(特别是Singleton),并不会神奇地保佑全局变量!
关于给变量名加上前缀:不要在变量名中包含类型前缀!在c++中,编译器已经对类型进行了充分的检查。包括类型最终会导致错误的名称。特别是对于全局变量,我对其前缀的建议是:每当您想要使用全局变量的前缀时,请停止正在做的任何事情!您正处于构建问题的过程中,您应该设法更改设计以消除对全局变量的需求!
c++ 11标准(草案n3337):
17.6.4.3.2全局名称[Global .names]
某些名称集和函数签名始终保留给实现:
-每个包含双下划线__或以下划线后跟大写字母(2.12)开头的名称保留给实现以供任何使用。
-每个以下划线开头的名称都保留给实现,以用作全局命名空间中的名称。
除此之外,对于您为全局变量选择的(标识符)名称没有任何限制。
这是一种惯例,一些人用g_
前缀全局变量,m_
前缀成员变量,等等。这是一个选择的问题;语言本身并没有强加这样的要求。因此,只要标识符以英文字母开头,您可以自由地为它们命名并加上任何前缀。
至于全局变量的使用,我想说,如果你刚刚开始学习c++,使用它们,然后受到伤害,然后意识到它们有多糟糕;您将看到为什么它们总是受到经验丰富的程序员的谴责。仅仅说他们不好并没有什么价值,有些事情最好是通过经验来学习。
- 当vector是tje全局变量时,c++中vector的内存管理
- 如果全局变量默认是外部变量,为什么要添加"extern"关键字?
- Visual C++: MSVC vs. GCC+CLANG: 处理 lambda 捕获类成员变量,正确的方法是什么?
- C++ 未初始化的本地(非全局)int 数组中的元素类型到底是什么?
- 存储变量的更有效方法是什么?
- 变量 BitMask 在函数 CeilLog2 中的实际效果是什么?
- 赋予全局变量而不是局部变量优先级的函数 - (异常行为)
- 这个变量在 C++ 中的范围是什么?
- 使用 gtest 框架在单元测试代码中检查目标对象的私有变量的最佳实践是什么?
- std::线程不是全局变量,但在到达创建它的函数的末尾时不会超出范围?
- 主窗口应该是全局变量吗?
- 将共享指针传递给函数参数 - 将其分配给局部变量的正确方法是什么
- 作为副本传递的 std::move()'d 变量的效果是什么?
- 从模块导出全局常量的正确方法是什么?
- 在C++中,变量声明左侧的大括号是什么意思?
- 有什么理由C++ 11+ std::mutex 应该声明为全局变量,而不是作为函数参数传递到 std::thread 中
- C 我应该做什么而不是全局变量
- 什么时候全局变量被认为是好的/推荐的做法
- 全局变量,它们到底是什么
- 全局对象和静态变量之间的破坏顺序是什么