考虑以下命名空间:
// foo.h
namespace foo
{
extern int bar;
}
//foo.cpp
namespace foo
{
extern int bar = 42;
}
有没有办法在项目的其他地方更改bar
的值(即,不在命名空间内)?
我的意思是:
// in some other .cpp file
#include foo.h
int setBar(int x)
{
foo::bar = x;
}
答案 0 :(得分:1)
有没有办法在项目的其他地方更改bar的值(即,不在命名空间内)?
是的,almost exactly as you've shown。
您的示例代码中唯一的问题是您在extern
文件中使用foo.cpp
来定义foo::bar
变量。您需要从extern
中删除foo.cpp
:
#include <iostream>
// foo.h
namespace foo
{
extern int bar;
}
//foo.cpp
namespace foo
{
int bar = 42; // no extern in cpp file.
}
int setBar(int x)
{
std::cout << "old foo::bar: " << foo::bar << std::endl;
foo::bar = x;
std::cout << "new foo::bar: " << foo::bar << std::endl;
}
int main()
{
setBar(999);
}
Outout:
old foo::bar: 42
new foo::bar: 999
答案 1 :(得分:0)
如果您将变量声明为extern
,那么您告诉编译器他不应在当前转换单元中定义变量,而是让链接器查找在另一个转换单元中定义的变量。因此extern
只声明一个变量,但不定义它。因此,初始化未定义的变量是没有意义的。
所以你应该写一下:
// foo.h
namespace foo
{
extern int bar; // Just declare...
}
//foo.cpp
namespace foo
{
int bar = 42; // Define and initialise
}
请注意,您仍然提供带有extern int bar
的标头文件,当foo.cpp
以外的其他翻译单元包含该文件时 - 声明变量bar
,即使代码可能引用它,即使它在另一个库中定义(例如在foo.o
)。