2008-11-14 35 views
9

Chuẩn C++ quy định rằng các biến thành viên bên trong một phần truy cập đơn lẻ phải được bố trí trong bộ nhớ theo cùng thứ tự mà chúng được khai báo. Đồng thời, các trình biên dịch được tự do lựa chọn thứ tự lẫn nhau của các phần truy cập. Sự tự do này làm cho nó không thể trong lý thuyết để liên kết các tệp nhị phân được tạo bởi các trình biên dịch khác nhau. Vì vậy, những lý do còn lại cho việc đặt hàng trong phần nghiêm ngặt là gì? Và có phải sắp tới C++ 09 chuẩn C++ 11 mới cung cấp một cách để xác định đầy đủ bố cục đối tượng "bằng tay" không?Bố cục lớp trong C++: Tại sao các thành viên đôi khi được yêu cầu?

+0

C++ 11 đã sửa đổi điều này để làm rõ rằng các thông số truy cập _repeated_ can thiệp (vì bất kỳ lý do ai đó có thể bao gồm) không cản trở bảo đảm bố cục; chỉ khi cấp độ truy cập thay đổi thông qua một trình chỉ định _different_, không phải là lần lặp lại của bước trước đó. –

Trả lời

8

Sự tự do này khiến cho lý thuyết không thể liên kết các tệp nhị phân được tạo bởi các trình biên dịch khác nhau.

Không thể vì một số lý do và bố cục cấu trúc là nhỏ nhất. vtables, triển khai của operator newdelete, kích thước loại dữ liệu ...

Vì vậy, lý do còn lại cho yêu cầu đặt hàng nghiêm ngặt là gì?

Khả năng tương thích C, tôi đã nghĩ, do đó cấu trúc được định nghĩa trong C gói giống như cách thực hiện trong C++ cho bộ biên dịch đã cho.

Và chuẩn C++ 11 mới cung cấp cách xác định đầy đủ bố cục đối tượng "bằng tay"?

Không, không quá tiêu chuẩn hiện tại.

Đối với trường hợp class hoặc struct không có vtable và hoàn toàn riêng tư (hoặc công khai), bạn có thể sử dụng loại [u]int[8|16|32|64]_t. Trường hợp sử dụng nào bạn có nhiều hơn thế này?

+0

> Trường hợp sử dụng nào bạn có nhiều hơn thế này? Tối ưu hóa.Các đối tượng có thể được làm nhỏ hơn bằng cách sắp xếp lại các thành viên dữ liệu của chúng. Thứ tự trong mã thường phản ánh các nhóm hợp lý của các thành viên, vì vậy bạn không muốn thay đổi điều đó. –

0

CHỈNH SỬA: Tôi sợ tôi đã hiểu nhầm câu hỏi của bạn

Tôi nghĩ rằng đó là tối ưu hóa để truy cập bộ nhớ. Ví dụ: nếu chúng tôi có cấu trúc này:

struct example 
{ 
    int16 intData; 
    byte byteData; 
    int32 intData; 
    byte intData; 
    int32 intData; 
} 

Giả sử từ trong nền tảng này là 32 bit. Sau đó, bạn sẽ cần 4 từ đầy đủ để vượt qua tất cả các dữ liệu trong struct:

int16 + byte = 24 bit (lĩnh vực netx không phù hợp ở đây)

int32 = 32 bit (lĩnh vực netx không phù hợp ở đây)

byte = 8 bit (lĩnh vực netx không phù hợp ở đây)

int32 = 32 bit

Nhưng nếu bạn sắp xếp lại lĩnh vực này s đến:

struct example 
{ 
    int16 intData; 
    byte byteData; 
    byte intData; 
    int32 intData; 
    int32 intData; 
} 

thì bạn có thể lưu một quyền truy cập bộ nhớ.

2

[sửa] Tôi đã học được điều gì đó mới mẻ ngay hôm nay! tìm thấy báo giá tiêu chuẩn sau đây:

không tĩnh dữ liệu thành viên của một lớp (phi đoàn) tuyên bố không có can thiệp access-specifier được phân bổ để các thành viên sau có địa chỉ cao hơn trong một lớp đối tượng . Thứ tự phân bổ thành viên dữ liệu phi tĩnh được ngăn cách bởi một số truy cập-specifier không được chỉ định (11.1). Yêu cầu thực hiện các yêu cầu có thể khiến hai thành viên liền kề thành viên không được phân bổ ngay lập tức sau mỗi khác; có thể yêu cầu không gian để quản lý các chức năng ảo (10.3) và các lớp cơ sở ảo (10.1).

Thú vị - tôi không biết tại sao mức độ tự do này được đưa ra. Tiếp tục để lần thứ còn lại của bài trả lời trước đây của tôi ...


Như đã đề cập, lý do giữ gìn trật tự là khả năng tương thích C, và trở lại sau đó tôi đoán suy nghĩ không ai lợi ích của các thành viên sắp xếp lại, trong khi bố trí bộ nhớ được thường được thực hiện bằng tay. Ngoài ra, những gì bây giờ sẽ được coi là "thủ thuật xấu xí" (như zeroing các thành viên được lựa chọn với memset, hoặc có hai cấu trúc với cùng một bố trí) là khá phổ biến.

Tiêu chuẩn không cung cấp cho bạn một cách để thực thi bố cục nhất định, nhưng hầu hết các trình biên dịch đều cung cấp các biện pháp kiểm soát đệm, ví dụ: #pragma gói trên trình biên dịch MSVC.

Lý do đệm tự động là tính di động nền tảng: các kiến ​​trúc khác nhau có các yêu cầu căn chỉnh khác nhau, ví dụ: một số kiến ​​trúc ném vào ints không thẳng hàng (và đây là những trường hợp đơn giản trở lại sau đó).

+0

Không, tôi chắc chắn anh ấy đúng. Tôi không có quyền truy cập vào tiêu chuẩn ở đây để tìm kiếm nó, nhưng tôi đã nhận thấy như vậy trước đây. Nó nói rằng đặt hàng giữa các phần truy cập khác nhau không được chỉ định, nhưng bên trong một phần, các thành viên được trình bày theo thứ tự khai báo. Tôi cũng tự hỏi điểm là gì – jalf

+0

Bạn nói đúng, tôi đã cập nhật câu trả lời. Bây giờ tôi cũng tò mò. – peterchen

+1

C++ 11 sửa đổi điều này để làm rõ rằng intervening _repeated_ access specifiers (vì bất kỳ lý do ai đó có thể bao gồm) không cản trở việc bảo đảm bố trí; chỉ khi cấp độ truy cập thay đổi thông qua một trình chỉ định _different_, không phải là lần lặp lại của bước trước đó. –

0

Bạn không bao giờ phải liên kết các đối tượng được tạo bởi các trình biên dịch khác nhau. Ngay cả khi những gì bạn nói về là thay đổi, bạn vẫn sẽ có nhiều vấn đề hơn mà ngăn cản bạn liên kết với các tập tin được tạo ra của trình biên dịch khác. (sắp xếp, đặt tên mangling, gọi quy ước để chỉ tên một vài người trong số họ).

Một lý do khiến trình biên dịch tự do đặt hàng các phần truy cập xung quanh có thể là do đó trình biên dịch có thể thiết lập thứ tự cho các phần truy cập: các thành viên có địa chỉ thấp hơn được bảo vệ nhiều hơn các thành viên có địa chỉ cao hơn.

Bạn sẽ không nhận được bất kỳ thứ gì nếu sắp xếp lại không được phép: Chỉ POD cung cấp khả năng tương thích C và cách cung cấp cho bạn số byte của thành viên bên trong lớp/struct (sử dụng macro offsetof) hoặc cho phép bạn ghi nhớ chúng. Một loại sẽ trở thành không phải POD nếu bạn định nghĩa một hàm tạo tùy chỉnh, sao chép hàm tạo, một thành viên riêng hoặc một số thứ khác. Đặc biệt, bắt nguồn từ một lớp học hiện đang phá vỡ PODness.

C++ 1x làm giảm yêu cầu đối với POD. Ví dụ, trong C++ 1x std::pair<T, U> thực sự là một POD, mặc dù nó cung cấp hàm tạo riêng của nó (mà phải phù hợp với các quy tắc nhất định).

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