2011-12-24 10 views
37

C11 hỗ trợ cấu trúc mang tính chất như vậy:Tại sao C++ 11 không hỗ trợ cấu trúc ẩn danh, trong khi C11 làm gì?

struct Foo 
{ 
    struct 
    { 
     size_t x, y; 
    }; 
}; 
struct Foo f; 
f.x = 17; 
f.y = 42; 

Về cơ bản, các thành viên của như một struct được đối xử như thể họ là thành viên của kèm theo struct hoặc union (đệ quy, nếu cấu trúc kèm theo là bản thân vô danh).

Lý do cơ bản cho C++ 11 cũng không bao gồm cấu trúc ẩn danh là gì? Chúng chỉ hữu ích một cách không phổ biến (chủ yếu là trong các công đoàn, để loại bỏ việc đánh máy mã định danh cho số struct). Nhưng chúng dường như là một sự bổ sung đủ rõ ràng cho đặc tả (và đã được nhiều trình biên dịch thực hiện) mà chắc chắn chúng phải được thảo luận, ít nhất là để duy trì tính tương thích với tiêu chuẩn C11. Vậy tại sao họ không được thêm vào?

+12

Tôi không đồng ý với phiếu bầu rằng câu hỏi này không mang tính xây dựng. Câu hỏi mềm hơn cũng được. – GManNickG

+6

__Practically speaking__ hầu hết các trình biên dịch C++ 11 đều hỗ trợ các cấu trúc ẩn danh. Tôi đã sử dụng chúng trong cả hai MSVC++ (kể từ khi, bao giờ) và với trình biên dịch llvm C++ 11 của Apple. – bobobobo

+0

MinGW cũng hỗ trợ kiến ​​trúc/cấu trúc ẩn danh. –

Trả lời

42

Ít nỗ lực để duy trì tính tương thích giữa C++ và C khi hai ngôn ngữ phát triển. Lưu ý rằng các mảng ngăn xếp độ dài biến đổi đã có trong C từ năm 1999, nhưng không được bao gồm trong C++ 11. Trong khi họ thường không giới thiệu những thứ mâu thuẫn với nhau, ủy ban C++ không chính xác uốn cong về phía sau để đảm bảo rằng C++ 11 tương thích với các phiên bản của C vượt quá C89.

Hơn nữa, tính năng này sẽ khá phức tạp trong C++, vì struct không có gì khác hơn là class. Và một cấu trúc/lớp ẩn danh nên có tất cả các đặc điểm của một cấu trúc/lớp thông thường, phải không? Nếu không, điểm của nó là gì?

Việc xây dựng một tên vô danh struct có ý nghĩa gì? Làm thế nào bạn sẽ xác định các nhà xây dựng? Một cái gì đó đơn giản như:

struct Foo 
{ 
    struct 
    { 
     size_t &x; 
    }; 
}; 

đơn giản là không thể vì bên trong struct không có hàm tạo. Và không có cách nào để chỉ định một. A struct không thể xây dựng các thành viên khác struct bên trong nó.

Đối với một cái gì đó như thế này:

struct Foo 
{ 
    size_t outer; 
    struct 
    { 
     void SomeFunc(); 
     size_t x; 
    }; 
}; 

this con trỏ không SomeFunc nhận được? Loại this là loại vô danh và không tên nào? Làm thế nào bạn thậm chí sẽ xác định SomeFunc bên ngoài của cấu trúc? Tên của SomeFunc không thể là Foo::SomeFunc, bởi vì SomeFunc sống trong phạm vi bên trong.

Quá phức tạp đối với C++ để giải quyết. Và chắc chắn không đủ đáng để làm phiền với việc thêm vào sự phức tạp đó.

+14

Điều này có ý nghĩa hợp lý, mặc dù tôi có thể tưởng tượng những hạn chế mà sẽ làm cho nó hoàn toàn hợp lý: POD, không có phương pháp (thừa kế hay cách khác), và hoàn toàn công khai, tôi nghĩ, giải quyết các vấn đề bạn nêu ra. Dường như với tôi rằng các công đoàn vô danh đã giới thiệu nhiều vấn đề này, nên vấn đề dường như không quá phức tạp đối với tôi, ngoại trừ cảm giác lái xe quá ít để giải quyết chúng. –

+11

"Xây dựng một cấu trúc không tên là gì? Bạn sẽ định nghĩa hàm tạo như thế nào?". Điều tương tự có thể được yêu cầu cho một liên minh vô danh. Các công đoàn cũng có thể có các nhà thầu. –

+0

Ngoài ra, hầu hết những gì bạn nhận được trong C11 từ các cấu trúc ẩn danh, bạn cũng có thể nhận được từ thừa kế. Các công đoàn ẩn danh sẽ hữu ích hơn, nhưng khi Nicol chỉ ra toàn bộ tính năng này là không phù hợp với C++. –

3

Để chơi tuyên bố chủ trương của ma quỷ - lớp và khai báo cấu trúc được sử dụng thường xuyên để bọc khai báo kiểu lớp cụ thể.

typedef struct { 

} name; 

do đó phải được cho phép.

Do đó

struct { 

} 

nên càng tốt.

Tuy nhiên, nếu chúng ta xem điều này chỉ là một khai báo trong không gian tên nội bộ của một lớp, sẽ không có cách nào để truy cập vào bên trong của cấu trúc.

Vì struct! = Không gian tên trong C, C có thể tạo nên các quy tắc như truy cập cấu trúc ẩn danh thông qua cấu trúc xung quanh.

Đối với C++ để cho phép điều này, nó sẽ cần phải trường hợp đặc biệt tình huống này, mà sẽ làm phức tạp độ phân giải tên.

Tất nhiên, chơi ủng hộ ma quỷ của quỷ dữ - C thực sự đã làm điều này. Nó bổ sung thêm một mức độ để phân giải tên - nếu bạn không thể tìm thấy tên trong một kiểm tra stuct các thành viên ẩn danh của struct. Đó là một chút huyền diệu, theo cách mà tôi có thể thấy các thành viên ủy ban C++ thấy khó chịu.

Nó cũng đặt ra các câu hỏi - nếu một cấu trúc ẩn danh có thể được truy cập thông qua lớp cha của nó, những gì về cấu trúc ẩn danh trong một không gian tên.

Tất nhiên, nếu bạn thực sự muốn biết, chỉ cần hỏi Stroustrup - anh ấy trả lời email.

+0

Đây không phải là lý do chính đáng --- công đoàn ẩn danh * được * hỗ trợ (ngay cả trong C++ 98!), Nhưng cấu trúc ẩn danh thì không? Nếu đây là lý do, thì các công đoàn vô danh cũng không được hỗ trợ vì chúng chia sẻ cùng một không gian tên như các cấu trúc. –

+0

Tôi tìm thấy "chút huyền diệu" chút vui. Đối với tôi trông giống như "Đây không phải là C. Chúng tôi quyết định. Neener-neener." – 6502

+0

C++ đã hỗ trợ các công đoàn ẩn danh và các không gian tên ẩn danh, nơi các nội dung tràn ra, như thể chúng được khai báo nội tuyến ở phạm vi bên ngoài. Các cấu trúc ẩn danh hoàn thành bộ ba đó (đặc biệt hữu ích trong lập trình đồ họa). Trong một khía cạnh khác, C++ 11 thậm chí còn vượt ra ngoài C và hỗ trợ các không gian tên nội tuyến (ngay cả khi được đặt tên, không chỉ là ẩn danh). http://stackoverflow.com/questions/11016220/what-are-inline-namespaces-for –

-2

Nó nghĩ làm việc này trong C++ 11

struct A 
{ 
    int someVariable; 
}; 

struct B : public A 
{ 
    int someOtherVariable; 
}; 

Sử dụng nó như:

B structB; 
structB.someVariable = 5; 
structB.someOtherVariable = 6; 

này đã giúp tôi để giải quyết một vấn đề tương tự.