2012-07-02 31 views
15

tôi đang trải qua điều tuyệt vời trên C++ POD, Trivial and Standard Layout classes Một tài sản tôi chưa hiểu rõ về cách bố trí giữa các ý kiến ​​như sau: -Chuẩn Layout C++

A standard layout has no base classes of the same type as the first 
    non-static data member 

Vì vậy, sau đây sẽ không phải là một Layout chuẩn vì nó có thành viên đầu tiên tương tự như các lớp cơ sở

struct NonStandardLayout3 : StandardLayout1 { 
    StandardLayout1 x; // first member cannot be of the same type as base 
}; 

Nhưng hiệu suất-khôn ngoan và tài sản khôn ngoan như thế nào là struct trên bất kỳ khác với

struct StandardLayout5 : StandardLayout1 { 
    int x; 
    StandardLayout1 y; // can have members of base type if they're not the first 
}; 

đó là sự điều chỉnh của phần trên đây.

+0

Related [post] (http://stackoverflow.com/q/7160901/183120). – legends2k

Trả lời

15

Lý do là loại bố cục chuẩn có hiệu quả ủy quyền "tối ưu hóa lớp cơ sở trống" nơi các lớp cơ sở không có thành viên dữ liệu chiếm không gian và có cùng địa chỉ với thành viên dữ liệu đầu tiên (nếu có) của lớp dẫn xuất. Tuy nhiên, cố gắng thực hiện điều này khi lớp cơ sở có cùng loại với thành viên dữ liệu đầu tiên vi phạm mô hình bộ nhớ C++ yêu cầu các đối tượng riêng biệt cùng loại phải có địa chỉ riêng biệt.

Từ ISO/IEC 14882: 2011 1.8 [intro.object]/6:

Hai đối tượng mà không phải là bit lĩnh vực có thể có cùng địa chỉ nếu người ấy là subobject của người kia, hoặc nếu ít nhất một là một lớp con lớp cơ sở có kích thước bằng không và chúng có các kiểu khác nhau; nếu không, họ sẽ có địa chỉ rõ ràng

uỷ quyền có hiệu quả các lớp cơ sở có sản phẩm nào, 9.2 [class.mem]/20:

Một con trỏ tới một đối tượng struct tiêu chuẩn bố trí, phù hợp chuyển đổi sử dụng một reinterpret_cast , trỏ đến thành viên ban đầu của nó (hoặc nếu thành viên đó là một trường bit, sau đó đến đơn vị mà nó cư trú) và ngược lại.

Các loại sau (Type1Type2) phải tương thích bố cục (mặc dù chúng sẽ là các lớp bố cục chuẩn) mà không bị hạn chế này.

struct S1 {}; 
struct S2 {}; 

struct Type1 : S1 { 
    S1 s; 
    int k; 
}; 

struct Type2 : S1 { 
    S2 s; 
    int m; 
}; 
+3

Đây chính xác là chú thích cho quy tắc này tại §9/7 nói: "[Quy tắc này] đảm bảo rằng hai đối tượng con có cùng loại lớp và thuộc về cùng một đối tượng có nguồn gốc nhất không được cấp phát tại cùng một địa chỉ" –

+0

'Type2' là lớp * bố cục tiêu chuẩn * theo C++ 14 và tiếp tục là lớp * bố cục tiêu chuẩn * theo N4606 và [C++ 1z] (http://eel.is/c+ + draft/class # 7), vì 'S1' không cùng kiểu với' S2'. – Belloc