2010-08-30 95 views
2

以下代碼不會編譯,而名稱「aNumber」在使用前未聲明。聲明在使用C++之前?

class A 
{ 
    A() 
     :aNumber(100) 
    { 
    } 
    void foo() 
    { 
     aNumber = 0; 

    } 
    int aNumber; 
}; 

如果上面的代碼編譯,那麼爲什麼不以下: - 由成員變量

A. 
class Dummy 
{ 
    void foo(INT); 
    typedef int INT; 
}; 

B.Default初始化: -

class Dummy 
{ 
    void foo(int y = x); 
    int x; 
}; 

回答

1

你在比較蘋果和橘子。下面的代碼是OK:

class A { 
    A() :aNumber(100) { INT bNumber = aNumber; } 
    void foo() { aNumber = INT(42); } 
    void bar(int bNumber = INT(1)) { aNumber = bNumber; } 
    int aNumber; 
    typedef int INT; 
}; 

的問題不是你聲明一下,但如果使用的聲明。 方法定義,即使它在詞類中出現在類中,也會被編譯,就好像它們是在類中聲明的一樣,但在類聲明的外部和後面定義,因此是默認參數。

+0

class A {A():aNumber(aStaicMember){} int aNumber; void foo(int x = aStaicMember); // aStaicMember還沒有被decalred靜態int aStaicMember; //聲明}; int A :: aStaicMember = 100; //定義當上面是真的那麼爲什麼不是typedef,我仍然感到困惑 – 2010-08-31 10:10:46

+0

我已經顯示你的typedef也是可以的,重要的部分是_where_你使用的名字,而不是名稱是typedef還是別的.chubsdad引用了相關的標準文本9.2/2。 – MSalters 2010-09-01 08:25:54

1

最簡單的方法來處理語言較少前置式返回通行證。在使用之前定義事物也會改善組織。

更多實質性的定義可以通過一個小前鋒聲明中介紹:

class Dummy 
{ 
    class bar; // declare first, but not a big deal 
    void foo(bar*); 
    class bar { ... }; 
}; 

樣品「B」不受聲明的順序。它說明了一個默認參數不能命名非靜態成員。

8
  1. 在編譯案例中,類中元素的順序是不相關的。
  2. typedef的情況下,訂單與IS有關,因爲在該範圍之外可見的名稱可能會被新的typename覆蓋。
  3. 第三個例子不合格,你不能用非靜態成員變量初始化。
2

對於點1:

$ 9.2/2 - 「的一類是在 類級閉合}認爲是 完全定義的對象類型(3.9) (或完整的類型)符。在類 成員的規範,該類是 視爲完整的函數內 機構,默認參數和 構造函數構造函數,初始化 (包括嵌套 類這樣的事情),否則被認爲是如 其自己的類內不完整 成員規範。「

因此INT必須在成員函數'foo'聲明之前定義。

對於第2點: 這裏的原因是'x'不是'Dummy'的靜態成員。 Dummy的非靜態成員需要一個對象表達式。

+0

對於第2點,我可以使用如下: - class Dummy { void foo(int y = this-> x); int x; }; 不,我不能! 爲什麼我不能? – 2010-08-31 08:48:08

+0

這解釋了什麼標準說,但我仍然不知道爲什麼它是這樣的原因。「$ 9.2/2」。 當「類被視爲在函數體內完成,默認參數和構造函數ctor-initializers」那麼爲什麼不爲函數聲明? – 2010-08-31 09:27:29

+0

@Sudhendu Sharma:'this'不能用於所示的默認參數聲明中,因爲'this'僅在'定義'或非靜態類成員函數和構造函數初始化列表中有效。 – Chubsdad 2010-08-31 09:48:23

0

該標準定義了成員名稱在成員某些部分範圍內的地方。見3.3.6/1

  • 在一個類中聲明的名稱的潛在範圍不僅包括以下 名稱的說明符聲明區,也是所有函數體,默認參數,並構造ctor- 初始化的在這個類中(包括嵌套類中的這些東西)。

「潛在範圍」是範圍的名稱有,如果它不是由任何其他名稱隱藏。請注意,「在名稱的聲明符後面」是一個不太正確的術語,因爲某些聲明沒有使用聲明符聲明(例如,嵌套的類聲明)。所以的C++ 0x改變了這種閱讀

在一個類中聲明的名稱的潛在範圍不僅包括以下 的名稱的申報點的聲明區,[...]

另一個人引用了標準的另一部分(9.2/2),這要求在某些部分認爲類類型是完整的。例如,這允許您在成員函數體內創建類的對象。