2010-04-27 41 views
6

Tôi quan tâm đến các hạt và chốt của C++ và tôi tự hỏi điều gì thực sự thay đổi khi một đối tượng được khởi tạo. Tôi đặc biệt quan tâm nếu các chức năng sau đó được thêm vào bộ nhớ, nếu chúng có từ thời gian chạy hoặc nếu chúng không bao giờ được lưu trữ trong bộ nhớ nào cả.Điều gì sẽ xảy ra trong bộ nhớ khi lớp C++ được khởi tạo

Nếu bất cứ ai có thể hướng dẫn tôi đến một trang web tốt trên một số bu lông cốt lõi của C và C++, tôi cũng thích điều đó.

Cảm ơn, Jo

Trả lời

1

Một trường hợp phổ biến là:

  1. Memory được phân bổ bằng cách gọi operator new. Chức năng này rất có thể đã có trong bộ nhớ, nó cần rất nhiều.
  2. Phương thức khởi tạo của lớp được gọi. Mã này có thể đã có trong bộ nhớ. Nếu không, cuộc gọi đến trang lỗi chức năng này. Hệ điều hành ghi chú và tải trang thích hợp từ tệp thực thi của bạn vào RAM. Sau đó nó cho hệ điều hành để thử lại. (2A. Ctor sắp xếp cho các hàm ảo có thể gọi được - thường bằng cách viết con trỏ vtable)
  3. Cơ hội là trang có hàm tạo cũng chứa các thành viên khác trong lớp của bạn. Những người đó có thể được gọi là quá. Nhưng nếu họ đang ở trên một trang khác, gọi họ có thể gây ra lỗi trang khác và tải khác.Nếu trình biên dịch của bạn đặt vtable trên một trang khác, việc sử dụng vtable đó cũng có thể gây ra lỗi trang.

Lợi thế của cơ chế tải theo yêu cầu này là hệ điều hành có thể tránh tải mã cho lớp CPrinter nếu người dùng không bao giờ dự định in tài liệu của mình.

1

Các chức năng đều được lưu trữ trong thực thi chính nó, vì vậy họ đang nạp từ get-đi.

Mọi bộ nhớ cần thiết cho đối tượng đó cho các biến thành viên được phân bổ.

Nếu bạn đang tự hỏi làm thế nào chức năng biết đối tượng nào đang được gọi, thì về cơ bản một con trỏ "này" vô hình được chuyển làm tham số đầu tiên cho hàm.

+0

Ngay cả khi đối tượng không có thành viên nào, nó vẫn được cấp phát một số bộ nhớ để đảm bảo rằng tất cả các đối tượng đều có địa chỉ bộ nhớ duy nhất. – Skizz

7

Không chắc chắn về một trang web tốt, nhưng Inside The C++ Object Model là một cuốn sách khá hay.

Ít nhất trong trường hợp thông thường, các hàm thành viên tồn tại hoàn toàn độc lập với mọi phiên bản của lớp. Thay vào đó, một cá thể của lớp là một cấu trúc chứa các thành phần dữ liệu (không tĩnh) của đối tượng. Nếu lớp có ít nhất trên hàm ảo, đối tượng cũng sẽ chứa một con trỏ tới vtable, mà về cơ bản là một mảng các con trỏ trỏ tới các hàm.

Khi hàm thành viên được gọi, địa chỉ của đối tượng đó được truyền dưới dạng tham số ẩn cho hàm (nhiều trình biên dịch dự trữ đăng ký chỉ dành cho nó) và trong hàm được gọi là này.

+0

Tôi chưa đọc, nhưng +1 cho TOC một mình. –

0

Khi một đối tượng được khởi tạo;

  1. Memory được phân bổ
  2. Các nhà xây dựng được thực hiện
  3. Các vtable được "thiết lập"

Số 3 là lý do tại sao nhà xây dựng không thể gọi chức năng ảo trong các lớp thừa kế (khi các nhà xây dựng được thực hiện vtable chưa được "thiết lập").

Bạn có thể nhận được hiệu ứng tương tự bằng cách sử dụng thành ngữ thư/phong bì. Xem Advanced C++ Programming Styles and Idioms cho việc này và hơn thế nữa.

+1

vtables, trong khi không được bảo đảm thực sự tồn tại theo tiêu chuẩn, có xu hướng được khởi tạo như một phần của khung công tác xây dựng. vtables có xu hướng được khởi tạo từ ít được bắt nguồn nhất để dẫn xuất nhất (theo cùng thứ tự trong đó các nhà xây dựng được khởi tạo). –

+0

@Nathan - Cảm ơn, tôi đã lập trình trên Windows quá lâu. Bạn có thể cho tôi biết về một trình biên dịch/nền tảng không sử dụng vtables không? –

0

Nói chung, khi một lớp được khởi tạo, khối bộ nhớ mới được cấp phát. Bộ nhớ được phân bổ chứa:

  1. Thành viên dữ liệu không tĩnh của lớp và các thành phần dữ liệu không tĩnh được kế thừa của lớp cơ sở.
  2. Nếu lớp có một hoặc nhiều hàm ảo, thì cá thể lớp cũng chứa con trỏ đến virtual function table của lớp đó.

Các chức năng của lớp không được sao chép khi tạo phiên bản mới. This sẽ giúp hiểu những gì tạo nên kích thước của đối tượng.

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