2010-02-07 41 views
18

Tại sao typedef không thể được sử dụng với tĩnh? Ví dụ: mã bên dưới là lỗiTại sao typedef không thể được sử dụng với tĩnh?

typedef static int INT2; 

Bạn nên làm theo các quy tắc nào khác để sử dụng typedef? Những từ khóa nào khác không thể được sử dụng với typedef?

Cảm ơn bạn rất nhiều!

+8

Cả typedef và tĩnh là lớp lưu trữ trong các ngôn ngữ (đúng đúng đối với C; Tôi tin rằng nó cũng đúng đối với C++). Bạn chỉ có thể có một lớp lưu trữ trong một khai báo đơn - bạn có hai trong ví dụ của bạn, do đó lỗi. –

+3

+1. "Trình định danh typedef được gọi là" bộ chỉ số lớp lưu trữ "cho chỉ tiện lợi cú pháp;" – dirkgently

Trả lời

31

typedef không khai báo một dụ của một biến, nó tuyên bố một loại (loại bí danh trên thực tế),

static là khuôn khổ vòng loại bạn áp dụng cho một ví dụ, không phải là một loại, vì vậy bạn có thể sử dụng tĩnh khi bạn sử dụng loại, nhưng không phải khi bạn xác định loại. Như thế này ..

typedef int int32; 
static int32 foo; 
+3

'static' không phải là một vòng loại, nhưng là một * bộ lưu trữ lớp *. Do đó, nó không phải là "một phần của loại" như các vòng loại như 'const', ví dụ: 'typedef const int ci; ci x = 42; '(các loại với các loại vòng loại khác nhau vẫn là cùng loại, nhưng có thể không tương thích). – dyp

+0

@John Knoeller Thanh lịch! Câu trả lời tuyệt vời! – Sohaib

20

Từ khóa static không phải là một phần của loại, tùy thuộc vào ngữ cảnh đó là bộ lưu trữ hoặc bộ định danh phạm vi và không ảnh hưởng đến loại nào. Do đó, nó không thể được sử dụng như là một phần của định nghĩa kiểu, đó là lý do tại sao nó không hợp lệ ở đây.

Một typedef là định nghĩa kiểu, tức là bạn đang nói 'tên này' bây giờ đề cập đến 'loại này', tên bạn đặt phải là số nhận dạng như được xác định theo tiêu chuẩn ngôn ngữ, loại phải là loại specifier, tức là một kiểu đã được đặt tên, hoặc kiểu cơ sở hoặc typedef'd, một struct, union, class, hoặc enum specifier, với các loại có thể có, tức là const, hoặc volatile.

Từ khóa tĩnh tuy nhiên không thay đổi loại, nó nói một cái gì đó về đối tượng, (nói chung, không phải trong ý nghĩa OOP.) Ví dụ: nó là biến được đặt trong bộ nhớ tĩnh, không phải là loại.

Có vẻ như bạn đang cố gắng sử dụng một typedef như một vĩ mô, ví dụ:

#define MYINT static int 
+1

Tại sao điều đó lại quan trọng? –

+0

@ the Douglas Adams fan: Tôi nghĩ rằng nó; có lẽ không rõ ràng như câu trả lời của Bailey. Các bộ định danh lưu trữ và các bộ định danh phạm vi không phải là các phần của * type * của một cái gì đó; chúng là một phần của cách các thể loại được lưu trữ hoặc phạm vi. –

+0

@Robert tốt, như từ khóa nói, đó là một loại defition, vì tĩnh không phải là một phần của loại, nếu không thể được sử dụng trong định nghĩa của một loại. – wich

7

thời gian lưu trữ được kết hợp với các đối tượng. Một khai báo typedef tạo ra một bí danh - một tên mới cho một kiểu. Nó không tạo ra các đối tượng. Do đó bạn không thể sử dụng một bộ lưu trữ với một typedef.

3

Tôi nghĩ rằng câu trả lời từ Mà và Bailey là đúng và đủ, nhưng để giúp làm rõ với những người mà nhận xét: Khi bạn khai báo một typedef loại quả phải phù hợp ở khắp mọi nơi nó có thể được sử dụng. Có gì nếu typedef bạn đã tạo xuất hiện trong đoạn mã sau:

INT2 myfunction() 
{ 
    return 0; 
} 

class MyClass 
{ 
    public: INT2 x; 
}; 

INT2 MyClass::x; 
  • Chức năng trở INT2 sẽ làm cho không có ý nghĩa. Tất nhiên giá trị trả về không phải là tĩnh (không thể).
  • Tuyên bố thành viên x trong MyClass sẽ tĩnh và cũng là định nghĩa sau này? Điều đó không chỉ thừa, là không chính xác, bởi vì bạn không sử dụng từ khóa tĩnh khi định nghĩa một thành viên tĩnh - chỉ khi khai báo nó.

Điều tương tự cũng áp dụng cho các từ khóa khác được Bailey đề cập. Hãy suy nghĩ về nó: các từ khóa duy nhất có thể tuyên bố một loại cho tất cả các sử dụng của nó là các kiểu nguyên thủy, và các kiểu bổ sung (const, unsigned, vv).

3

Như nhiều người khác đã đề cập, static là trình chỉ định lớp lưu trữ, không phải loại.Điều này có nghĩa là, cụ thể là từ khóa static cho biết trình biên dịch về một biến nên được đặt ở đâu, có hay không nó sẽ xuất hiện như một biểu tượng cho liên kết bên ngoài hoặc biến tồn tại trong bao lâu.

Loại là giải thích về vị trí bộ nhớ. Đó là mô tả loại dữ liệu nào sống ở vị trí đó và được kết hợp với một tập hợp các hoạt động có thể được thực hiện trên dữ liệu đó.

Vì vậy, loại và lớp lưu trữ chỉ liên quan ở chỗ cả hai đều nói điều gì đó về một phần dữ liệu. Từ khóa typedef là để tạo tên mới cho các loại.

Đối với một sự tương tự ngẫu nhiên ...

Một loại giống như nói về một kiểu dáng và mẫu xe cụ thể.

Một lớp lưu trữ giống như nói rằng một chiếc xe được lưu trữ trong một nhà để xe nước nóng riêng và chỉ được sử dụng trên một đường đua tư nhân.

typedef là biệt hiệu cho một mẫu và kiểu dáng cụ thể.

2

typedef không thể sử dụng cùng với static vì cả hai lớp typedefstatic là các lớp lưu trữ. Nếu bạn xác định biến là typedef static int a; thì có tồn tại nhiều lớp lưu trữ cho biến a.

Lớp lưu trữ được sử dụng để xác định phạm vi (mức hiển thị) và thời gian sống của các biến và/hoặc chức năng. Một số ví dụ là static, auto, register, extern, typedef, vv

+0

Điều này thật thú vị! Thật vậy, 'typedef' được xác định là một * bộ lưu trữ-lớp-specifier *, mặc dù" cho cú pháp thuận tiện chỉ "6.7.1/3. – dyp

+0

Jonathan Leffler nói về điều tương tự trong một [bình luận cho OP] (http://stackoverflow.com/questions/2218435/why-typedef-can-not-be-used-with-static#comment2172109_2218435). – dyp

Các vấn đề liên quan