Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 匿名名称空间中声明的常量与函数范围静态常量相比有哪些优点?_C++_Static_Namespaces_Constants - Fatal编程技术网

C++ 匿名名称空间中声明的常量与函数范围静态常量相比有哪些优点?

C++ 匿名名称空间中声明的常量与函数范围静态常量相比有哪些优点?,c++,static,namespaces,constants,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_字符串中声明一个静态变量 // source.cpp co

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

# Pseudocode
function get_string(i)
  return my_string_array[i]
end
字符串将硬编码到应用程序中。函数原型在头文件中声明:

// header.h
const std::string &get_string(const int i);
在我看来,我有两个选项来声明硬编码字符串

选项#1:在
get_字符串中声明一个静态变量

// 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];
}
对于这个有限的用例,这些声明在功能上是等价的吗?程序处理函数中的静态常量是否与全局声明的常量或匿名命名空间中声明的常量不同?


我知道明显的可访问性差异(即,在本地名称空间中声明的常量对同一翻译单元中定义的所有函数全局可用),但这可以被视为一种优势,具体取决于场景,因此,对于这个问题,可以忽略这个差异。

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

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

为什么不把它们放在
constchar*
global数组中呢

[编辑]


正如我上面所建议的,全局数组不是正确的方法。另外要考虑的是使用选项1,而不是字符串数组来创建<代码> const char */COD>字符串文字数组。std::string对象的数组将复制字符串文本。您可能还必须返回
const char*
——因此,这可能不是您想要的。

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

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

为什么不把它们放在
constchar*
global数组中呢

[编辑]


正如我上面所建议的,全局数组不是正确的方法。另外要考虑的是使用选项1,而不是字符串数组来创建<代码> const char */COD>字符串文字数组。std::string对象的数组将复制字符串文本。您可能还必须返回
const char*
——因此,这可能不是您想要的。

我能想到的唯一区别是,全局变量在输入
main
之前在程序开始时初始化;而函数静态仅在第一次调用函数时初始化。在您的情况下,区别可能并不重要。如果没有其他人直接使用它,请在函数本身中定义它(理想情况下,没有人应该这样做,否则函数本身就没有用途)。除此之外,在访问元素之前,您必须检查
i
的值是否超出范围。@Nawaz-不用担心,根据您的用例,如果编译时已知
i
,则一定会执行边界检查:-),您可以使
get_string
成为一个模板函数,将
i
作为模板参数,并使用模板专门化返回适当的字符串。您可能在运行时确定
i
,因此这可能不起作用,只是抛出了一些选项。我能想到的唯一区别是全局变量在进入
main
之前在程序开始时初始化;而函数静态仅在第一次调用函数时初始化。在您的情况下,区别可能并不重要。如果没有其他人直接使用它,请在函数本身中定义它(理想情况下,没有人应该这样做,否则函数本身就没有用途)。除此之外,在访问元素之前,您必须检查
i
的值是否超出范围。@Nawaz-不用担心,根据您的用例,如果编译时已知
i
,则一定会执行边界检查:-),您可以使
get_string
成为一个模板函数,将
i
作为模板参数,并使用模板专门化返回适当的字符串。您可能在运行时确定
i
,所以这可能不起作用,只是抛出选项。为什么不将它们放在const char*global数组中呢。。为什么
const char*
?为什么完全是全局的?我认为这会解决“静态初始化顺序失败”的问题,我指的是“const char*”的静态数组。我同意应该推荐使用
选项1
。“静态初始化顺序失败”与元素为
std::string
无关,因此,如果它在本例中出现,则不能通过将
std::string
替换为
const char*
来修复它。嗯,对-这样的全局数组仍然必须在初始化期间分配。为什么不将它们放在const char*全局数组中呢。。为什么
const char*
?到底为什么?我