Làm thế nào là các đối tượng OOP và các lớp học và các lớp khác được tổ chức trong bộ nhớ theo ngôn ngữ lắp ráp?


13

Làm thế nào các đối tượng được tổ chức trong bộ nhớ?

Chẳng hạn, tôi biết rằng một hàm là một đoạn mã trong bộ nhớ, dự kiến ​​các tham số thông qua ngăn xếp và / hoặc các thanh ghi và xử lý khung ngăn xếp của chính nó.

Nhưng các đối tượng là một cấu trúc phức tạp hơn nhiều. Họ được tổ chức như thế nào? Có phải mỗi đối tượng có "liên kết" đến các phương thức và truyền địa chỉ cho chính nó đến phương thức đó không?

Sẽ thật tuyệt khi thấy một lời giải thích tốt về chủ đề này.

CẬP NHẬT. Tôi đã đặt câu hỏi chính xác hơn và tôi chủ yếu quan tâm đến việc gõ các ngôn ngữ tĩnh.


4
Nó có thể khác nhau giữa các ngôn ngữ khác nhau, đặc biệt là giữa các ngôn ngữ được gõ động và gõ tĩnh. Bạn có thể thu hẹp câu hỏi của bạn xuống các ngôn ngữ OO mà bạn quan tâm nhất không?
Bart van Ingen Schenau 16/07/2016

Tôi đã cập nhật câu hỏi, vì vậy tôi nghĩ các ngôn ngữ gõ động khó hiểu hơn.
Nikolai Golub

Câu trả lời:


17

Nếu không có công văn động (đa hình), "phương thức" chỉ là các hàm có đường, có lẽ với một tham số bổ sung ngầm định. Theo đó, các thể hiện của các lớp không có hành vi đa hình về cơ bản là C structs cho mục đích tạo mã.

Đối với công văn động cổ điển trong một hệ thống kiểu tĩnh, về cơ bản có một chiến lược chiếm ưu thế: vtables. Mỗi phiên bản có một con trỏ bổ sung tham chiếu đến (một đại diện giới hạn) loại của nó, quan trọng nhất là vtable: Một mảng các con trỏ hàm, một cho mỗi phương thức. Do tập hợp đầy đủ các phương thức cho mọi loại (trong chuỗi thừa kế) được biết đến tại thời điểm biên dịch, nên người ta có thể gán các chỉ số liên tiếp (0..N cho các phương thức N) cho các phương thức và gọi các phương thức bằng cách tra cứu con trỏ hàm trong vtable sử dụng chỉ mục này (một lần nữa chuyển tham chiếu thể hiện dưới dạng tham số bổ sung).

Đối với các ngôn ngữ dựa trên lớp động hơn, bản thân các lớp thường là các đối tượng hạng nhất và mỗi đối tượng thay vào đó có một tham chiếu đến đối tượng lớp của nó. Đến lượt, đối tượng lớp sở hữu các phương thức theo một số cách phụ thuộc ngôn ngữ (trong Ruby, các phương thức là một phần cốt lõi của mô hình đối tượng, trong Python chúng chỉ là các đối tượng chức năng với các hàm bao nhỏ xung quanh chúng). Các lớp thường lưu trữ các tham chiếu đến (các) siêu lớp của chúng và ủy thác việc tìm kiếm các phương thức được kế thừa cho các lớp đó để hỗ trợ siêu lập trình có thêm và thay đổi các phương thức.

Có nhiều hệ thống khác không dựa trên các lớp, nhưng chúng khác nhau đáng kể, vì vậy tôi sẽ chỉ chọn một phương án thiết kế thú vị: Khi bạn có thể thêm các phương thức (bộ) mới cho tất cả các loại theo bất kỳ nơi nào trong chương trình ( ví dụ: các lớp loại trong Haskell và các đặc điểm trong Rust), toàn bộ các phương thức không được biết trong khi biên dịch. Để giải quyết điều này, người ta tạo ra một vtable cho mỗi tính trạng và chuyển chúng xung quanh khi yêu cầu thực hiện tính trạng. Đó là, mã như thế này:

void needs_a_trait(SomeTrait &x) { x.method2(1); }
ConcreteType x = ...;
needs_a_trait(x);

được tổng hợp xuống đây:

functionpointer SomeTrait_ConcreteType_vtable[] = { &method1, &method2, ... };
void needs_a_trait(void *x, functionpointer vtable[]) { vtable[1](x, 1); }
ConcreteType x = ...;
needs_a_trait(x, SomeTrait_ConcreteType_vtable);

Điều này cũng có nghĩa là thông tin vtable không được nhúng trong đối tượng. Nếu bạn muốn tham chiếu đến một "thể hiện của một đặc điểm" sẽ hành xử chính xác khi, ví dụ, được lưu trữ trong các cấu trúc dữ liệu có chứa nhiều loại khác nhau, người ta có thể tạo một con trỏ béo (instance_pointer, trait_vtable) . Đây thực sự là một khái quát của chiến lược trên.


5

Đây là câu trả lời theo nghĩa của câu tục ngữ "nếu bạn cho một người đàn ông một con cá bạn nuôi anh ta một ngày, trong khi nếu bạn dạy anh ta câu cá bạn nuôi anh ta cả đời" vì câu hỏi của bạn rất rộng

1. nghiên cứu các nguồn thông tin mở

Google cho "lập trình hướng đối tượng lắp ráp" liệt kê khá nhiều tài nguyên có liên quan khác nhau.

ví dụ: Lập trình hướng đối tượng trong hội, Ethan J. Eldridge, ngày 15 tháng 12 năm 2011 là liên kết thứ 3 và có vẻ tốt

2. học hỏi từ mã viết tay hiện có

Bạn có thể thấy nó hoạt động như thế nào bằng cách nghiên cứu mã nguồn được viết bằng một số ngôn ngữ lắp ráp phổ biến với OOP được khai báo rõ ràng, vd

3. tìm hiểu từ các mẫu mã được tạo bởi trình biên dịch

Bạn có thể thấy nó hoạt động như thế nào bằng cách nghiên cứu các tệp ngôn ngữ lắp ráp trung gian được tạo bởi trình biên dịch OOP mà bạn chọn. Cả hai trình biên dịch C ++ và FreePascal đều có thể được cấu hình để bạn có thể thấy phiên âm của mã OOP cấp cao vào mã ngôn ngữ lắp ráp trông như thế nào

4. giải câu đố với ý thức chung của bạn

Bây giờ thì đã quá muộn vì bạn đã biết những gợi ý từ những câu trả lời khác. Nhưng trước khi internet rất dễ tìm kiếm và trước đó có những trang web mà bạn có thể nhận được câu trả lời của mình mà không cần bất kỳ nỗ lực nào trong vòng vài giờ miễn phí từ một số tình nguyện viên đã học nó một cách khó khăn, phương pháp làm việc duy nhất miễn phí cho bất kỳ ai là

Hãy tự hỏi: "tôi sẽ thực hiện nó như thế nào?"

Rất thường sau vài ngày của quá trình suy nghĩ nền tảng chạy trong tâm trí của bạn và sau khi vứt bỏ một số thiết kế dự thảo giấy, bạn sẽ thấy rằng giải pháp bạn đưa ra rất giống với giải pháp mà các lập trình viên khác đã đưa ra và đã thực hiện


Bây giờ là ý kiến ​​trả lời của tôi dựa trên, không trả lời trực tiếp câu hỏi của OP và người dùng cao cấp có thể tự do đánh giá thấp tô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.