在匿名命名空间中声明的常量与函数范围静态常量的(dis)优点是什么?

时间:2016-03-30 14:34:59

标签: c++ static namespaces constants

我想定义一个函数,当给定一个整数时,它将返回一个字符串。像这样:

# Pseudocode
function get_string(i)
  return my_string_array[i]
end

字符串将被硬编码到应用程序中。函数原型在头文件中声明:

// header.h
const std::string &get_string(const int i);

我看到它的方式,我有两个声明硬编码字符串的选项。

选项#1:在get_string

中声明一个静态变量
// source.cpp
const std::string &get_string(const int i)
{
    static const std::string values[] = {
        std::string("foo"),
        std::string("bar"),
        std::string("baz"),
    };

    // Assume bounds checking is performed on i.

    return values[i];
}

选项#2:在匿名命名空间中声明全局常量

// source.cpp
namespace
{
    const std::string values[] = {
        std::string("foo"),
        std::string("bar"),
        std::string("baz"),
    };
}

const std::string &get_string(const int i)
{
    // Assume bounds checking is performed on i.
    return values[i];
}

对于这个有限的用例,这些声明在功能上是否相同?程序中的静态常量是否与全局声明的常量或匿名命名空间中声明的常量不同?

我知道显而易见的可访问性差异(即在本地名称空间中声明的常量对于在同一个翻译单元中定义的所有函数全局可用),但是根据场景的不同,这可以作为一种优势,因此为了这个问题的目的,可以省略这种差异。

1 个答案:

答案 0 :(得分:2)

在get_string函数中定义为静态数组的字符串将在第一个get_string调用时构造,而全局命名空间中的字符串将在应用程序启动时构造。

因此,两种方法可能产生的问题都不同。例如,如果你在全局范围内定义字符串,那么你不应该在执行main之前使用它,否则你永远不知道它们是否被构造。如果你在get_string内部使用静态构造,至少在c ++ 11之前你可能会遇到线程问题,之后魔法静态应该为你解决这个问题。

为什么不把它们放在const char*全局数组中?

[编辑]

如上所述,全局数组不是正确的方法。您要考虑的另一件事是使用选项1,但不是字符串数组创建const char*字符串文字数组。 std :: string对象的数组将复制您的字符串文字。您可能还必须返回const char* - 所以也许这不是您想要的。