2014-02-19 109 views
6

這兩種方法有什麼區別?用「class」關鍵字聲明一個變量vs在函數聲明中聲明一個沒有「class」關鍵字的變量

有時當我編譯時錯誤,抱怨編譯器不能識別 函數簽名中的某些類類型,那麼如果我在各個變量前面添加關鍵字「class」,它總能解決這種編譯時錯誤。

例如,如果編譯器無法識別的類型客戶

void recv(Client * c) 

那麼,如果我將其更改爲

void recv(class Client * c) 

問題就解決了。

對不起,我不能拿出一個具體的例子,因爲我隨機提出這個問題。

+0

從來沒有聽說過。你可以給[SSCCE](http://sscce.org/)顯示這個錯誤嗎? – delnan

回答

12

在類型參數聲明中使用關鍵字類,結構體,枚舉稱爲詳細類型說明符。它在聲明函數的範圍中引入了新類型。 它與前向聲明類似。

還有另一種使用這種聲明。例如,如果對象或函數名稱的名稱隱藏了具有相同名稱的類或枚舉。例如

struct A {}; 

A A; // now A is seen as an identifier of the object 

void f(struct A); 
+0

所以在這種情況下,我們需要函數f的簽名中的關鍵字struct來區分A和第二行中聲明的變量名稱A. –

+0

@ phresnel是的,你是對的。 –

1

在這種情況下

void recv(Client * c) 

編譯器查找的Client聲明。如果找不到,則會報錯。您可以通過提前聲明解決它,如以下

class Client; 
void recv(Client * c) 

雖然我從來沒有見過第二個案例,但是這看起來也是在這裏聲明類客戶端。

1

如果您需要以class作爲參數的前綴,這意味着編譯器還不知道名爲Client的類。看看下面的人爲的例子:

int main(int argc, char *argv[]) 
{ 
    MyClass m; 

    return 0; 
} 

class MyClass 
{ 
}; 

因爲MyClass聲明的主要功能後,當它試圖創建變量m,和你的程序將拒絕編譯的主要功能是不知道叫MyClass類的。

爲了解決這個問題,你通常會使用一個正聲明:

class MyClass; // <-- Forward declare MyClass. 

int main(int argc, char *argv[]) 
{ 
    MyClass m; 

    return 0; 
} 

class MyClass 
{ 
}; 

在你的情況下,函數參數類型前使用class關鍵字基本上向前聲明的類名稱爲您服務。

+0

那麼這意味着我可以在文件的最開始處向前聲明類客戶端,而不必在函數簽名中使用詳細的類型說明符,就像我上面做的那樣? –

+0

@takwing - 是的,我期望如此。 –

1

編譯器必須知道函數參數的類型。由於您明顯不提供定義,例如通過包含Client的標題,您必須提供前向聲明。這就是你在第二個例子中所做的(以一種不尋常的方式),所以編譯器知道Client是一個類。由於您只使用指針,因此聲明就足夠了,您現在不需要定義。