2014-09-04 52 views

回答

5

有两个方面对这一问题

方面1

C++阵列是固定尺寸的,其尺寸需要其中在编译时是已知的。如果决定需要在运行时延期,那么数组表达式会变得格格不入。

方面2

声明一个成员变量为非静止使得一个实例变量,其中只有一旦对象被实例化,其在运行时完成的存在的值。静态变量是一个类变量,其值可以在编译时确定。

你的具体例子成为经典的鸡蛋悖论。

class armon 
{ 
    static const int maxSize=10;  

    int array[maxSize]; 

} 
  • 为了实例您armon类,你需要知道它的大小。
  • 为了知道它的大小,你需要知道每个成员的大小。在你的特定情况下,你需要知道数组的大小。
  • 为了知道数组的大小,您需要知道因变量maxSize的值。
  • 为了访问因变量maxSize,您需要实例化类armon
  • 为了实例化你的类armon,你需要知道它的大小。

所以,你的阵列大小因变量应该是常量表达式,其在特定情况下应该是一个静态变量,

14

它不是是静态的,但它必须是常量表达式

C++标准§8.3.4 [dcl.array](重点煤矿):

如果常数表达式(5.19)时,它应是一个类型为std一个转换常量表达式:: size_t型,其值应大于零


也就是说,下面也是正确的:

constexpr std::size_t Size() { return 10; }; 

struct Y 
{ 
    int array[Size()]; 
}; 

注:

由于编译器需要知道类的大小,你不能做到这一点:

struct Y 
{ 
    const int size = 10; 
    int array[size]; 
}; 

可能使得Y不同情况下具有不同的尺寸。

另外请注意,在这种情况下,int array[size]常量表达式,因为它利用的this,参见C++标准部§5.19 [expr.const]:

甲条件表达式e是一个核心常数表达式,除非按照抽象机(1.9)的规则评估e,将评估以下表达式之一:

- 这个(5.1.1),除了constexpr函数或constexpr构造tor正在被评估为e的一部分;

(的size评价是真的this->size

+0

这是由于这样的事实,编译器能够在编译期间保留存储器。一个很好的解释[这里](http://stackoverflow.com/questions/21350478/what-does-memory-allocated-at-compile-time-really-mean) – lifeOfPI 2014-09-04 09:42:40

+0

你还需要解释为什么'const int maxSize = 10 ;'不考虑给出一个常量表达式,但'static const int maxSize = 10'为 – 2014-09-04 10:03:34

+0

@MattMcNabb当然,注意添加 – quantdev 2014-09-04 10:15:49

1

它不必是静态的,它必须是恒定的。

当你在一个类中声明一个常量时,你将为该类的每个实例创建一个常量

此外,如果您的maxSize只是const您将不得不初始化它在构造函数初始值设定项列表中,因为const maxSize被视为其值不能更改的变量。

类内const 关键字意思是“这是在该对象的孔寿命期间的常量”。 相同类别的不同对象可以具有该常数的不同值。

但是当它是一个静态常量时,将会有对于该类的所有实例只有一个常量。这意味着你必须在你定义它的同一行上初始化常量值。

+0

“如果你的maxSize只是const,你必须在构造函数初始化列表中初始化它”是错误的!它也可以是一个范围变量,它不会在初始化程序列表中初始化。 “类const关键字内部的意思是”这是在该对象的洞寿命期间的常量“”也是错误的。这只是程序员的一个“暗示”。想一想'const_cast <>' – lifeOfPI 2014-09-04 09:48:58

+2

@lifeOfPI:这不仅仅是一个提示。你不能抛弃const_ness并以非const方式使用对象。这将是未定义的行为,并可能以非常意想不到的方式破裂。一种意想不到的方式就是编译器可能创建了一个常量的多个副本,而且只会更改一个常量。 – MSalters 2014-09-04 09:58:04

+0

您不必在构造函数初始值设定项列表中初始化它,例如'诠释计数= 0;'在OP的代码。 – 2014-09-04 10:04:36

相关问题