3

更推荐哪种方式来声明字符串 const?

  1. 是在文件范围内声明全局变量。
  2. 将其声明为类的全局。

该变量将仅在类成员函数中使用。我倾向于觉得 2 更好,因为它仅特定于类成员函数。

A.cpp
---------------------
static const std::string hello_str = "Hello";

void A::print()
{
    std::cout << hello_str;
}

(或者)

A.h
---------------------
class A{
public:
    static const std::string hello_str;
    void print();
}

A.cpp
---------------------
const std::string A::hello_str = "Hello";

void A::print()
{
    std::cout << A::hello_str;
}

编辑-1:

让我说 hello_str 的内容可以改变。例如。每当他对文件进行更改时,开发人员都会手动更新该字符串。

在这种情况下,将变量初始化保留在函数中是否有意义?用户更新字符串可能不清楚/不明显。如果它对文件 (1) 或类 (2) 保持全局,则其他开发人员可以“识别”并修改此字符串。

鉴于上述用例,您仍然建议使用返回字符串的函数吗?或者我可以使用类级别的静态变量(带有私有访问说明符)吗?

4

2 回答 2

4

匿名命名空间是另一种选择:

A.cpp

namespace {
  const std::string hello_str("Hello");
}

void A::print() {
    std::cout << hello_str;
}

但是您应该真正将其包装在延迟初始化的函数中。

这将采取以下形式:

A.h
---------------------
class A{
public:
    static const std::string& hello_str();
    void print();
}

A.cpp
---------------------
const std::string& A::hello_str() {
  static const std::string str("Hello"); // << constructed on first call of A::hello_str()
  return str;
}

void A::print() {
    std::cout << A::hello_str();
}

在这种情况下,您也可以简单地按值返回,并完全避免静态/全局。您的 std c++ 库实现可能使用所谓的“小字符串优化”——如果是这样,则不需要堆分配来创建或移动这么短的字符串。

另请注意,您的两个示例不一样;一个实际上是私有的,另一个是公开可见的。

最终,您不应该使用您提出的任何一种方法。考虑延迟初始化的函数中的静态,或者(在许多情况下甚至更好)按值返回。

回答你原来的问题:我赞成课堂内的声明,但私人的。我发现这在事件实现发生变化时更容易维护。当然,如果外部实现可以以某种方式访问​​ cpp 中的静态,那么您可能还希望在类中将其声明为私有,以便其他人无法访问它。

于 2012-08-30T04:56:22.777 回答
2

简单的规则:

  • string逻辑上属于类,因此它应该是类成员 。
  • 类的所有实例共享相同的字符串,因此它属于该类而不是类的特定实例(所有实例共享相同的字符串),因此使其成为static成员。

这为您提供了以下优势:

  • 只有需要访问字符串的类成员才能访问,这与将其声明为全局字符串不同。
于 2012-08-30T04:53:58.360 回答