2011-04-18 55 views
6

我真的很困惑。我正在閱讀Bjarne Stroustrup的TC++ PL(特刊,第19版 - 2010年9月)。讓我引用這本書的一部分,突出我的困惑:是一個typedef的定義嗎?

char ch; 
string s; 
int count = 1; 
const double pi = 3.1415926535897932385; 
extern int error_number; 

const char* name = "Njal"; 
const char* season[] = { "spring", "summer", "fall", "winter" }; 

struct Date { int d, m, y; }; 
int day(Date* p) { return p->d; } 
double sqrt(double); 
template<class T> T abs(T a) { return a<0 ? -a : a; } 

typedef complex<short> Point; 
struct User; 
enum Beer { Carlsberg, Tuborg, Thor }; 
namespace NS { int a; } 

從這些例子可以看出,一個聲明可以做的不是簡單地 有名稱的類型關聯更多。大多數這些聲明也是定義;也就是說,它們也爲它們所指的名稱定義了一個實體。對於ch, 該實體是將適當的內存量用作變量 - 即將分配內存。這一天是指定的功能。對於 常數pi,它是值3.1415926535897932385。對於日期,該實體是 的一種新類型。 對於Point而言,它是複雜類型,因此Point變爲複合的 的同義詞。上述聲明的,只有這些是不是也 定義:

double sqrt(double); 
extern int error_number; 
struct User; 
typedef complex<short> Point <-- WTF; 

沒有與它下面給出的列表中以粗體衝突的句子? typedef只是一個聲明還是一個定義?這是書中的錯誤嗎?

+1

'Bjarne的-stroustrup'是一個標籤呢? – 2011-04-18 15:31:01

+0

看起來像是一段時間的標籤。 – 2011-04-18 16:03:43

回答

6

雖然我完全被這個困惑。標準很明確。 Typedef只是一個聲明。沒有定義。

3.1-2

的聲明是除非 它聲明瞭一個功能,而不 指定函數體(8.4)的定義, 它包含extern聲明符 (7.1.1)或(7.5),既不是初始化函數也不是函數體,它在類聲明 (9.4)中聲明瞭一個靜態的 數據成員,它是類名聲明 (9.1),或者它是typedef 聲明(7.1.3), using-declaration(7.3.3)或 using-directive(7.3.4)。

編輯:哦,我剛剛意識到了爲什麼。您可以鍵入一個聲明,因此typedef必須是聲明本身。

+0

的確,typedef只是引入了一個同義詞,並且你不需要實例化一個同義詞。 – 2011-04-18 16:09:17

0

的定義創建一個對象,所以:

int x; 

是稱爲X的int的定義。 typedef不會創建一個對象,它會爲現有類型創建一個新名稱,所以它不是一個定義。

+1

'struct Date {int d,m,y; };'不會創建對象 - 它仍然是(類型)定義。 – sepp2k 2011-04-18 15:12:37

+0

是什麼讓你認爲定義必須創建一個對象?內聯函數的定義可能不會造成任何定義。一個類的定義也可能不會產生任何結果。只有對象的定義會創建一個對象。 – 2011-04-18 15:15:00

2

typedef是一個類型別名,而不是自己的新類型。有了typedef,沒有新的定義,而是一個現有的定義被賦予了第二個名字 - 就像夜宵是你的別名,而不是你的真名,但它們都指的是同一個實體:你。

+0

沒有這種類型的別名。 – 2011-04-18 15:30:19

+0

@Let_Me_Be - 你怎麼稱呼它,然後(除了「type typedef」或者像這樣)? – 2011-04-18 15:49:15

+0

@Let_Me_Be:你什麼意思?別名是某種東西的另一個名稱。而這正是typedef的一個類型的另一個名稱。 – 2011-04-18 15:49:24

1

你如何區分定義的聲明和不是的聲明?

簡單:您只能有一個定義每個實體,但只要你想要的聲明。

因爲你可以說

typedef int Foo; 
typedef int Foo; 

沒有任何問題,這不是一個定義。或者因爲這不是一個定義,你可以這樣說。無論哪種方式,您的編譯器都可以輕鬆分辨出哪個是哪個。

注意,在C是非法的重複的類型定義,所以typedef聲明定義在C