为什么本地类中不允许使用静态数据成员?

时间:2011-11-17 06:27:17

标签: c++ static static-members local-class

为什么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 个答案:

答案 0 :(得分:22)

从标准9.4.2节:

  

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

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

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

我认为理论上它们只允许你在局部类中使用静态const积分类型,只要它们只用在整数常量表达式中,但它可能只会给标准体和编译器带来太大的负担。供应商差异化,实用价值很小;本地静态变量可以从本地类访问,因此使用本地静态const应该同样好。

答案 1 :(得分:4)

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

另外不要忘记你可以在the.class之外创建一个本地const变量,你可以在类中使用它,只要你只读它的值(也就是说,只要你不带take.its.address)。

答案 2 :(得分:2)

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

  abc.h

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

   int myClass::number = 314;

现在,由于void abc(int x)中的作用域不是全局的,因此没有用于定义静态成员的作用域。

答案 3 :(得分:-1)

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

class test
{
public:
    const int FOO = 123;

    [...snip...]
};

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

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

但是,在大多数情况下,函数中定义的类将完全优化,因此这是一种很好的处理方式(我的类中有50%的类具有这样的变量成员!)