2010-02-04 90 views
7

我能做到這一點爲什麼我不能多聲明一個類

extern int i; 
extern int i; 

不過雖然在這兩種情況下沒有記憶是暫時我不能做同樣的一類

class A { 
.. 
} 
class A { 
.. 
} 

分配。

+0

它們應該是兩個不同的類嗎?或部分班? – Naveen 2010-02-04 08:48:49

+0

@all 其實我的理解是定義和聲明之間的區別事實是 - 後者沒有分配內存。這就是爲什麼我認爲A類{..}更多是一個聲明而不是一個定義。 – deeJ 2010-02-04 09:30:48

回答

25

以下是聲明

extern int i; 
class A; 

而接下來的兩個是定義

int i; 
class A { ... } 

的規則是:

  • 的定義也是聲明。
  • 在使用它之前,您必須已經「看到」一個項目的聲明。
  • 重新聲明是可以的(必須是相同的)。
  • 重新定義是一個錯誤(一個定義規則)。
+0

你說得好。我撤回我的回答 – 2010-02-04 08:56:12

+3

對於它的價值,這被稱爲一個定義規則。 – GManNickG 2010-02-04 08:58:59

+6

您可以添加 「A級」; 事實上,是類A的聲明。 – Klaim 2010-02-04 08:59:11

2

第一個(extern)引用了現有的變量。所以你只是指出了兩次變量。

類聲明給出了一個類型(你的類:A)的含義。你試圖給A兩個含義。這對你沒有任何用處,只能混淆,所以編譯器可以保護你。

順便說一句,如果你把兩個類放在不同的命名空間中,你可以給它們相同的名字。

0

但在第一種情況下,這並不矛盾。

extern int i; 
extern double i; 

也不起作用。 因此,如果您創建A級時間,則無法確定A是誰。

3

最接近相當於extern int i一類是正向的聲明,這是你喜歡,你可以做很多次:

class A; 

class A; 

class A; 

class A{}; 

當你定義的實際類,你說多少內存需要構建它的一個實例,以及如何佈置這些內存。雖然這不是真正的問題。

1

你可以做

class A; 

經常只要你想,然後在一個文件中與

class A { ... } 

實例把它定義爲這樣:
classB.h:

class A; 
class B { A *a; } 

classA。H:

class B; 
class A { B *b; } 
+0

這是行不通的:編譯器需要看'B'的定義來計算'A'的大小。儘管如此,指針或引用仍然可以正常工作。 – 2010-02-04 09:12:52

+0

@roger:謝謝,糾正。我的C++知識有點生疏 – dbemerlin 2010-02-04 09:35:01

1

可以聲明類和對象多次,你不能做的就是定義不止一次。

extern使這是一個聲明,而不是定義(因爲沒有初始化):

extern int a; 

的身體,使你的class的定義,而不僅僅是一個聲明。你可以定義一個類。

+0

更確切地說,extern是關於鏈接的。可以用extern定義,如extern int a = 7; – 2010-02-04 09:03:08

+0

是的,但在這種情況下,'extern'更重要的作用是它將聲明更改爲不是定義。 – 2010-02-04 09:29:11

0

我想真正的問題是'你爲什麼要?'。當您在同一翻譯單元(.cpp文件)中多次包含頭文件時,情況有時會出現。如果是這樣的話,你應該看看使用include guards來保持編譯器的快樂。

這可能會給您帶來問題的另一個原因是您使用的第三方庫定義了與您自己的類名稱衝突的類。在這種情況下,您應該查看使用名稱空間來解決歧義。

在這兩種情況下'extern int i;'引用同一個對象(在別處聲明),因此多個聲明是明確的。如果您寫道:

extern int i; 
extern float i; 

編譯器會抱怨模糊(因爲它不知道你打算哪個變量來操作,如果你寫了「I = 0;」

複製類的聲明引起到聲明不同的可能性;再次,編譯器在遇到'A foo'時如何知道使用哪一個?'我猜編譯器可以比較類聲明並驗證它們實際上是相同的,但這會是當替代解決方案(命名空間,包括守衛,重命名)變得如此簡單(並且可能不會讓最終讀取代碼的人感到困惑)時,可以付出很多努力。

0

它與聲明vs定義無關。問題是類型與對象。

extern int i; 

告訴在類型的對象int存在的程序,它的名字是i。因爲它是extern沒有爲它分配存儲空間這裏是,但是在別的地方,可能在另一個翻譯單元中,它被定義併爲其分配存儲空間。

class A { 
.. 
}; 

限定命名A。它不分配任何對象或變量。它在運行時完全沒有區別,並且沒有爲其分配存儲空間,因爲它不是一個對象。它只是向編譯器引入了一個新的類型。從這一點開始,您可以創建類型爲A的對象,而他們將爲其分配存儲空間

0

我給了它一些想法。我意識到類不是數據類型,它是定義數據類型的推動者。

所以在

extern int i; 
extern int i; 

int是一種數據類型。所以我們重新聲明一個不是數據類型的變量。

但在

class A {...}; 
class A {...}; 

A是數據類型。我們正在重新定義一個數據類型,當然這是不允許的。

相關問題