【问题标题】:Why does public const not imply static?为什么 public const 不暗示静态?
【发布时间】:2020-12-09 11:48:24
【问题描述】:

在 C# 中,const 意味着静态,因此您可以引用公共 const,而不必引用类或结构的实例。在 C++ 中,情况并非如此。如果要访问 C++ 中的 const 成员变量,首先需要引用该类的实例。据我所知,在 C++ 中,创建成员变量 const 会导致其数据被替换为文字值或存储在程序的文本或数据段(取决于编译器)中。所以我的问题是,如果 const 成员变量只为给定类(不是每个实例)分配一次,并存储在与实例特定成员数据分开的区域中,为什么你不能在没有引用的情况下访问公共 const 类成员变量类的一个实例,例如:

struct Example {
   const int array[] = {1, 2, 3};
};

void main() {
   std::cout << Example::array[1];
}

相反,您需要将它们设为静态常量并在类之外初始化它们,例如:

struct Example {
   static const int array[3];
};

const int Example::array[3] = {1, 2, 3}

void main() {
   std::cout << Example::array[1];
}

【问题讨论】:

  • "如果 const 成员变量只为给定的类分配一次" 是什么让你认为它是这样工作的?
  • 类的非静态const 数据成员在该类的不同实例中可以具有不同的值。 const 只是表示一旦初始化就不能修改。
  • @G.M.感谢您的澄清,我不知道 const 变量可能会因this stack overflow question 导致我相信而因实例而异。我认为这也意味着在这些情况下,它们实际上与每个实例数据的其余部分一起存储在堆栈或堆中,而不是存储在数据或文本部分中。
  • 在 C# 中,const 类成员可能只有一个(即每个类)实例。 C++ 的每个类实例都有一个const 成员实例(并且该成员可以在初始化包含对象时由构造函数初始化)。一个类的成员通常不是static,除非特别声明为static。更普遍的问题是“ 这样做,为什么 C++ 这样做不同?”有一个普遍的答案“因为 C++ 和 是不同的语言,旨在满足不同的目的”。
  • @Ryoku 请注意,您链接的问题是关于 C,而不是 C++。 C 根本没有类,因此从 C 如何做任何事情中得出关于 C++ 如何存储有关类成员变量的信息的结论是危险的。

标签: c++ static constants


【解决方案1】:

仅仅因为成员是const 并不意味着它在所有实例中都具有相同的值。考虑:

 struct foo {
     const int x = 1;
     foo(int a) : x(a) {}
 };

 foo a{1};
 foo b{2};

现在abconst int 成员具有不同的值。我不知道 C#,但是当你不能拥有 const 非静态时,它看起来好像缺少一些东西 成员。另一方面,const 成员在 C++ 中存在一些缺点,最简单的方法是完全避免它们以支持封装(当没有 setter 并且成员从未在类中修改时,它基本上是恒定的)。

请注意,即使成员 = 1; 有一个默认初始化程序,这并不意味着所有实例都具有相同的 x 值。默认初始化器仅适用于构造函数未在其成员初始化列表中提供初始化器时,但在上面的示例中它提供了。

【讨论】:

  • 感谢您的澄清。我仍然觉得奇怪的是,如果你设置了const int x = 1,你就不能在没有实例引用的情况下访问成员变量,尽管它对于类的每个实例都是常量,但至少我可以明白为什么在一般情况下它不适用。
  • @Ryoku 我想您指的是默认初始化程序。见编辑。它不会改变不同的实例可以有不同的 x 值的事实
  • @Ryoku • 我还是觉得很奇怪... 如果您想要一个类变量而不是实例变量,请使用static。这在 C++ 中不应该是“奇怪的”,它已经成为语言的一部分很长时间了。
  • @largest_prime_is_463035818 你是对的,这是一个完美的解释,谢谢。我不知道它只是一个默认初始化器,如果没有提供其他初始化器。
  • @Ryoku 还注意到,static 是 C++ 关键字之一,其含义可能非常不同。不过,从您的示例中可以清楚地看出您的意思。
猜你喜欢
  • 2011-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多