从外部更改命名空间变量值(C ++)

时间:2017-05-07 20:18:00

标签: c++ namespaces extern

考虑以下命名空间:

// 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;
}

2 个答案:

答案 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)。