extern如何在名称空间中工作
How does extern work in namespaces?
我正在运行一个类似于我在这里找到的简单程序。这是为了减少在多个文件中包含常量时的代码膨胀。它通过在命名空间内使用const全局变量及其各自的extern
forward声明来实现这一点。
上面
#ifndef GLOBALS_H_
#define GLOBALS_H_
namespace Constants
{
// forward declarations only
extern const double pi;
extern const double avogadro;
extern const double my_gravity;
}
#endif
globals.cpp
namespace Constants
{
// actual global variables
extern const double pi(3.14159);
extern const double avogadro(6.0221413e23);
extern const double my_gravity(9.2); // m/s^2 -- gravity is light on this planet
}
source.cpp
#include <iostream>
#include <limits>
#include "globals.h"
int main()
{
double value_of_pi = Constants::pi;
std::cout << value_of_pi;
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n');
std::cin.get();
return 0;
}
我假设Constants::pi获取了包含在global .cpp Constants命名空间中的值pi,并且能够这样做是因为它可以从包含的global .h访问命名空间本身。我不明白的是为什么const全局定义/初始化在globals.cpp中需要extern
关键字?我试图在global .cpp中删除extern
关键字,认为它不需要,但如果没有它们,我的程序将无法运行。我以为extern
只用于远期申报?为什么const全局定义/初始化需要它们?这与定义它们的名称空间有关吗?
当在多个文件中包含常量时,这意味着减少代码膨胀
我建议不要关注这种优化,除非真的有必要,而是选择最简单的设计:直接在头文件中定义这些常量,并从需要访问这些常量的所有翻译单元(".cpp文件")中包含该头文件。由于这些对象是const
,它们将具有内部链接,并且链接器不会因为违反单一定义规则而对您大喊大叫。
我试图在global .cpp中删除外部关键字,认为它不需要,但我的程序没有它们就无法运行
这是因为具有静态存储时间的名称空间范围const
对象(如pi
变量)具有内部链接,除非您显式地将它们定义为extern
。
我以为extern只用于向前声明?
extern
用于声明在另一个翻译单元(".cpp文件")中定义的变量。如果对象是const
,定义它的翻译单元需要显式地将其标记为extern
,以便它具有外部链接并从其他翻译单元可见(如果对象不是const
,则不需要这样做)。
是否与定义它们的命名空间有关?
不,这是所有具有静态存储时间的名称空间级const
对象的规则,它在段落[basic]中指定。c++标准/3:
如果名称是
,则具有命名空间作用域(3.3.6)的名称具有内部链接(3.1)[…-一个变量、函数或函数模板静态声明;或者,
(3.2) - 非易失性const限定类型的变量,既没有显式声明为extern,也没有预先声明为具有外部链接;或者
(3.3) -匿名联合的数据成员。
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- QSqlquery prepare()和bindvalue()不工作
- 不使用与左右停止工作命名空间 std 的简单比较
- 使用两个命名空间只能部分工作
- 请告诉我在巴泽尔拥有多平台工作空间的更好方法
- 即使在包含 std 命名空间之后,fstream 在 Visual Studio 2017 中也无法正常工作
- 如何让非成员在<N>命名空间中为自定义类工作 [C++17]
- 检测在ofstream写入过程中的空间不足,stream.fail()无法正常工作
- Ubuntu,如何找到内核工作繁重的程序热点?似乎kernel.kallsyms上的函数没有标记为用户空间函数的子级
- C++余弦在没有 std 命名空间的情况下工作 - 为什么
- 为什么 c++ 命名空间中的定义在命名空间之外工作
- 运算符重载解析在命名空间中工作
- C++ 如果某处有空间,则窗口系统 ( "path" ) 无法正常工作
- 命名空间和私有变量如何在程序集中工作
- 嵌套名称空间是如何工作的
- 进程外内存堆围绕32位地址空间工作
- TFS 2013构建如何使工作空间文件可编辑
- 为什么 <conio.h> 有时不起作用,并且在 C++ 中使用命名空间 std 可以工作
- extern如何在名称空间中工作
- Eclipse CDT/Qt:有一个Qt Gui项目依赖于工作空间中的另一个c++项目