2014-09-04 54 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

相關問題