大声限制对命名空间中定义的全局变量的访问
Restricting access loudly to a global variable defined in a namespace
考虑到头文件中的以下内容,我在名称空间方面遇到了一个小问题:
namespace A {
namespace B {
void SetMemberValue(double value) { _member = value; }
double FunctionThatUsesMember(double a) { return a * _member; }
double AnotherFuncThatUsesMember(double a) { return a / _member; }
static double _member = 0.01;
}
}
我不希望用户能够通过A::B::_member = some_value
更改_member
的值。在阅读了未命名的名称空间后,我将其更改为:
namespace A {
namespace B {
void SetMemberValue(double value) { _member = value; }
double FunctionThatUsesMember(double a) { return a * _member; }
double AnotherFuncThatUsesMember(double a) { return a / _member; }
namespace {
double _member = 0.01;
}
}
}
这迫使用户使用提供的mutator功能,除了一个问题外,效果很好:
如果用户继续使用:A::B::_member = some_value
,则代码不会编译、链接或运行失败;该语句被简单地忽略,并且使用0.01
的默认值,这可能导致运行时错误或"OMG WTF is WRONG BBQ!!1!!"时刻。(声明没有失败可能是MSVC++和VS2010的问题,尽管我不确定。)
问题:当A::B::_member = some_value
被错误使用时,有没有办法让代码以某种方式LOUDLY失败?
首先,请注意,在每个翻译单元中都会得到不同版本的_member
!我不确定这是不是故意的。
如果您确实希望程序中有一个_member
,并且不希望用户访问特定的全局变量,那么不应该在头中显示它!将其放入源中,并提供在那里访问它的功能:
// some-module.h
double getValue();
void setValue(double value);
// some-module.cpp
#include "some-module.h"
static double value(0.01);
double getValue() { return value; }
void setValue(double value) { ::value = value; }
我省略了名称空间,因为它们实际上并不重要。您可以在翻译单元中使用未命名的名称空间,而不是static
,但这并没有多大区别。
如果您声称额外的函数调用是不可接受的,并且所有内容都必须在标头中,那么您可以将value设置为类的私有成员。您仍然需要将其封装到一个函数中,以避免重复的符号。如果您还将类包装到一个未命名的名称空间中,那么每个翻译单元也可以有一个版本的值:
#if ONE_VALUE_PER_TRANSLATION_UNIT
namespace {
#endif
class Value
{
static double& value() { static double rc(0.01); return rc; }
friend double getValue();
friend void setValue(double value);
};
double getValue() { return Value::value(); }
void setValue(double value) { Value::value() = value; }
#if ONE_VALUE_PER_TRANSLATION_UNIT
}
#endif
显然,在所有这些情况下,您都可以添加更多访问该值的函数。我刚刚演示了使用简单的非成员函数getValue()
和setValue()
进行访问。你真正暴露的是你自己。
- QT C++中对全局变量的未定义引用
- 跨多个类的全局变量而不会出现重定义错误?
- 包括一个类来定义全局变量参数 c++ :(
- 访问另一个.cpp文件中的.cpp文件中定义的全局变量
- 在主循环外部多个文件上定义全局变量
- 是否可以通过全局变量定义具有可变参数数的函数中的参数数量
- 如何访问从C 编译的动态库中定义的全局变量
- 即使在定义类后也无法在C++中声明全局变量?
- 我们可以通过使用 "dot" 运算符在类之外定义类变量来制作全局变量吗?
- 当在其中定义全局变量时,如何在.cpp中包含 C 样式的 .h
- 在 main() 中定义全局变量
- 我可以在 MFC 应用程序中定义全局变量的位置
- 如何定义全局变量,以便所有类都可以访问/编辑它们
- C++:重新定义全局变量
- c++定义全局变量
- 如何声明和定义全局变量,以便从所有头文件/源文件中正确访问它们
- 在mpi中定义全局变量
- 如何在c++中单独的文件中定义全局变量
- 无法在C++中定义全局变量
- 在头文件中定义全局变量时,重复架构x86_64的符号