31

为什么static const成员不能存在于本地类中的原因是什么?这似乎是一个相当愚蠢的限制。

例子:

void foo() {
  struct bar {
    int baz() { return 0; }   // allowed
    static const int qux = 0; // not allowed?!?
  };
}

struct non_local_bar {
  int baz() { return 0; }   // allowed
  static const int qux = 0; // allowed
};

引用标准(9.8.4):

本地类不应具有静态数据成员。

4

4 回答 4

27

从标准第 9.4.2 节:

如果静态数据成员是 const 整型或 const 枚举类型,它在类定义中的声明可以指定一个常量初始化器,它应该是一个整型常量表达式。在这种情况下,成员可以出现在其范围内的整数常量表达式中。如果在程序中使用该成员,则该成员仍应在名称空间范围内定义,并且名称空间范围定义不应包含初始值设定项。

基本上,本地类没有链接,静态数据成员需要链接。

由于无法在命名空间范围内定义本地类的静态数据成员(带有初始化程序的声明不是定义),因此不允许使用它们,无论它们是否为 const 整数类型。从表面上看,编译器似乎应该能够内联该值,但是如果您尝试访问指向该成员的指针会发生什么?使用命名空间范围的类,您只会收到链接器错误,但本地类没有链接。

我想从理论上讲,只要它们仅用于整数常量表达式,它们就可以只允许您在本地类中使用静态 const 整数类型,但这可能会给标准机构和编译器供应商带来过多的负担来区分实用价值很小;本地静态变量可以从本地类访问,因此使用本地静态常量应该同样好。

于 2011-11-17T07:07:20.257 回答
5

我不认为有一个原因。不允许使用普通静态数据成员,因为在声明后无法定义它们。

另外不要忘记,您可以在.class 之外创建一个本地 const 变量,只要您只读取它的值(即,只要您不使用.its.address),您就可以在类内部使用它。

于 2011-11-17T06:34:34.137 回答
3

类的静态成员需要在全局范围内定义,例如

  abc.h

   class myClass {
   static int number;
  };
     abc.cpp

   int myClass::number = 314;

现在,由于 void abc(int x) 内部的范围不是全局的,因此没有定义静态成员的范围。

于 2011-11-17T06:33:23.483 回答
-1

随着事情的进展,我们现在有了 C++11,你可以在你的类中定义整型常量变量成员。

class test
{
public:
    const int FOO = 123;

    [...snip...]
};

当您使用 C++11 编译时,它可以工作。请注意,static未使用关键字。在打开优化的情况下进行编译时,这些变量可能都会被优化掉。但是,在调试中,它们作为常规变量成员出现在您的结构中。

但是请注意,类/结构的大小仍将包含该变量。所以这里变量 FOO 可能是 4 个字节。

然而,在大多数情况下,函数中定义的类将被完全优化,所以这是一种很好的做事方式(我的 50% 的类都有这样的变量成员!)

于 2014-05-15T08:26:44.180 回答