Tại sao kích thước của lớp trong c ++ phụ thuộc vào trạng thái công khai / riêng tư của các thành viên dữ liệu?


23

Từ những gì tôi biết, kích thước của một lớp trong c ++ phụ thuộc vào các yếu tố dưới đây -

  1. Kích thước của tất cả các thành viên dữ liệu không tĩnh.
  2. Thứ tự của các thành viên dữ liệu.
  3. Nếu đệm byte được kích hoạt hay không.
  4. Kích thước của lớp cơ sở ngay lập tức của nó.
  5. Sự tồn tại của các chức năng ảo.
  6. Chế độ thừa kế (thừa kế ảo).

Bây giờ tôi đã tạo 2 lớp như dưới đây -

class A{
    int a;
    short s;
    int b;
    char d;
};// kept a char at last on purpose to leave a "hole"

class B : public A{
    char c;  
};

Bây giờ kiểm tra kích thước của A và BI xem

  • kích thước của A: 16
  • kích thước của B: 16

giả định của tôi là char c trong lớp B được chứa trong "lỗ" còn lại trong lớp A.

Nhưng, điều làm tôi bối rối là kịch bản dưới đây trong đó tôi công khai các thành viên

class A{
    public:
    int a;
    short d;
    int b;
    char s;
};

class B : public A{
    public:
    char c;
};

Bây giờ kích thước trở thành

  • kích thước của A: 16
  • kích thước của B: 20

Tôi dường như không thể hiểu lý do cho sự khác biệt này.


1
Tại sao kích thước của lớp trong c ++ phụ thuộc vào trạng thái công khai / riêng tư của các thành viên dữ liệu? - Không. Đó là những chi tiết thực hiện phụ thuộc vào trình biên dịch.
PaulMcKenzie

1
Vậy bạn đang sử dụng trình biên dịch nào?
Romen

2
@PaulMcKenzie Thật ra nó có. Tiêu chuẩn bắt buộc các thành viên có cùng quyền truy cập được nhóm lại với nhau để thay đổi sẽ thay đổi chiến lược đệm của trình biên dịch.
NathanOliver

@ NathanOliver-ReinstateMonica, tôi không biết điều đó. Bạn có tham khảo phần có liên quan tiện dụng không?
R Sahu

@RSahu Nhìn nó để đưa vào câu trả lời của tôi chặt chẽ bây giờ.
NathanOliver

Câu trả lời:


8

Itanium ABI sử dụng định nghĩa P ++ của C ++ để định nghĩa các lớp là "POD cho mục đích bố trí". Việc các thành viên dữ liệu riêng tư loại bỏ một lớp khỏi tổng hợp và do đó POD trong C ++ 03:

Một POD-struct là một lớp tổng hợp mà không có thành viên dữ liệu tĩnh không của loại phi POD-struct, không POD-đoàn (hoặc mảng các loại như vậy) hoặc tham khảo, và không có toán tử gán bản sao người dùng xác định và không hàm hủy do người dùng định nghĩa.

Là một lớp POD sẽ vô hiệu hóa tái sử dụng phần đệm đuôi :

DSize, nvsize và nvalign của các loại này được định nghĩa là kích thước và căn chỉnh thông thường của chúng. Các thuộc tính này chỉ quan trọng đối với các loại lớp không trống được sử dụng làm lớp cơ sở. Chúng tôi bỏ qua phần đệm đuôi cho POD vì phiên bản đầu tiên của tiêu chuẩn không cho phép chúng tôi sử dụng nó cho bất kỳ điều gì khác và vì đôi khi nó cho phép sao chép loại nhanh hơn.

Do đó, trong ví dụ đầu tiên của bạn, Akhông phải là POD cho mục đích bố trí và có thể sử dụng phần đệm đuôi của nó B::c, nhưng trong ví dụ thứ hai của bạn, nó là POD và phần đệm đuôi của nó không thể được sử dụng lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.