c++ - 大声限制对命名空间中定义的全局变量的访问

标签 c++ namespaces unnamed-namespace

我有一个与 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 是错误的 BBQ!!1!!”时刻。 (声明未失败可能是 MSVC++ 和 VS2010 的问题,但我不确定。)

问题A::B::_member = some_value 被错误使用时,有没有办法让代码以某种方式大声失败?

最佳答案

首先,请注意您在每个翻译单元中得到不同版本的 _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; }

我省略了 namespace ,因为它们实际上并不重要。您可以在翻译单元内使用未命名的命名空间而不是 static,但这并没有太大区别,真的。

如果您声称额外的函数调用是 Not Acceptable 并且所有内容都必须在 header 中,您可以将值设为类的私有(private)成员。您仍然需要将它包装到一个函数中以避免重复的符号。如果您还将类包装到一个未命名的命名空间中,那么每个翻译单元也可以有一个版本的值:

#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() 的访问。您真正暴露的内容取决于您。

关于c++ - 大声限制对命名空间中定义的全局变量的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18521384/

相关文章:

c++ - 链表C++中的赋值运算符

c++ - 不持有锁的本地静态初始化避免了 C++11 中可能出现的死锁?

c++ - 显式模板参数规范

c++ - Qt 4.8.6 中的 qlabel mailto 链接

php - 在没有反斜杠的命名空间中使用函数

c++ - 嵌套未命名的命名空间?

python : access namespace of called script

c# - 向 C# 命名空间添加描述

c++ - 函数与来自未命名命名空间的参数的链接

c++ - 未命名命名空间内名称的外部链接