2012-06-10 26 views
25

Khi nào tôi nên xác định loại dưới dạng cấu trúc hoặc dưới dạng lớp?Tùy chọn sử dụng giữa cấu trúc và lớp trong ngôn ngữ D

Tôi biết rằng cấu trúc là các loại giá trị trong khi các lớp là loại tham chiếu. Vì vậy, tôi tự hỏi, ví dụ, tôi nên xác định một ngăn xếp như là một cấu trúc hoặc một lớp học?

Trả lời

31

Lý do # 1 để chọn cấu trúc so với lớp: các lớp có thừa kế, cấu trúc thì không. Nếu bạn cần đa hình, bạn phải sử dụng các lớp.

Lý do # 2: cấu trúc thường là loại giá trị (mặc dù bạn có thể biến chúng thành các loại tham chiếu nếu bạn làm việc ở đó). Các lớp luôn là kiểu tham chiếu. Vì vậy, nếu bạn muốn có một loại giá trị, hãy chọn một cấu trúc. Nếu bạn muốn có một kiểu tham chiếu, nó dễ nhất để đi với một lớp.

Lý do thứ 3: Nếu bạn có một kiểu với rất nhiều các thành viên dữ liệu, sau đó bạn có thể sẽ muốn có một kiểu tham chiếu (để tránh sao chép đắt tiền), trong trường hợp này, có lẽ bạn đang đi chọn một lớp.

Lý do # 4: Nếu bạn muốn hủy diệt xác định loại của mình, thì đó sẽ cần phải là cấu trúc trên ngăn xếp. Không có gì trên GC đống có hủy diệt xác định, và destructiors/finalizers của các công cụ trên đống GC có thể không bao giờ được chạy. Nếu chúng được thu thập bởi GC, thì finalizers của họ sẽ được chạy, nhưng nếu không, họ sẽ không. Vì vậy, nếu bạn muốn loại của bạn tự động bị phá hủy khi nó rời khỏi phạm vi, bạn cần phải sử dụng một cấu trúc và đặt nó trên ngăn xếp.

Đối với trường hợp cụ thể của bạn, bình thường phải là loại tham chiếu (sao chép tất cả các phần tử của chúng mỗi khi bạn vượt qua xung quanh sẽ cực kỳ tốn kém) và Stack là một thùng chứa, vì vậy bạn sẽ muốn sử dụng một lớp học, trừ khi bạn muốn đi đến những rắc rối của việc làm cho nó một cấu trúc ref-tính, đó là decidedly nhiều công việc. Nó chỉ có lợi thế là đảm bảo rằng destructor của nó sẽ chạy khi nó không được sử dụng nữa. Trên một lưu ý phụ, nếu bạn tạo một container là một lớp, bạn có thể sẽ muốn làm cho nó cuối cùng để các chức năng khác nhau của nó có thể được inlined (và sẽ không được ảo nếu lớp đó không làm gì cả ''), bạn có thể sử dụng nó. t xuất phát từ bất cứ điều gì khác hơn là Object và chúng không có chức năng mà Object có), điều này có thể quan trọng đối với một thứ gì đó giống như một nơi chứa hiệu suất chắc chắn quan trọng.

+0

Giả sử lớp container có thể lưu trữ tất cả các giá trị trong một kiểu nút: nếu tôi đặt nó làm cấu trúc, bất cứ khi nào tôi xóa nút và nút chính nó chứa giá trị tham chiếu (đối tượng của lớp), tham chiếu có bị xóa không? Exemple: Danh sách! Object lisObj; ... Object obj = new Object; lisObj.add (obj) lisObj.remove (Obj); // obj vẫn tồn tại? – Fred

+0

Chỉ vì tò mò, thư viện Phobo hoàn chỉnh về container là bao nhiêu? Những gì nó có và những gì còn thiếu? – Fred

+1

Bất cứ thứ gì được cấp mới đều là rác được thu thập. Nếu bạn muốn một cái gì đó trên heap được giải phóng tại một thời điểm cụ thể, sau đó sử dụng malloc và miễn phí để quản lý bộ nhớ của họ. Đối với các container của Phobos, chúng ở trong std.container, và chúng hiện đang khá thưa thớt, bởi vì các công cụ phân bổ tùy chỉnh vẫn đang được sắp xếp, và chúng ta đang đợi để thực hiện trước khi viết tất cả các container, bởi vì nếu không nó sẽ dẫn đến việc làm lại rất nhiều công việc khi chúng tôi thêm các trình phân bổ tùy chỉnh. Nếu các kiểu built-in và std.container không đủ, hãy xem tại http://www.dsource.org/projects/dcollections –

5

đọc "D"iving Into the D Programming Language

Trong D bạn sẽ có được cấu trúc và sau đó bạn sẽ có được lớp học. Họ chia sẻ nhiều tiện nghi nhưng có các điều lệ khác nhau: cấu trúc là các loại giá trị, trong khi các lớp học có nghĩa là cho đa hình động và được truy cập chỉ bằng tham chiếu. Bằng cách đó nhầm lẫn, lỗi liên quan đến cắt và nhận xét à la // Không! KHÔNG được kế thừa! không tồn tại. Khi bạn thiết kế một loại, bạn quyết định trả trước cho dù đó sẽ là một giá trị đơn hình hay một tham chiếu đa hình. C++ nổi tiếng cho phép xác định các loại giới tính mơ hồ, nhưng việc sử dụng chúng hiếm, dễ bị lỗi và đủ phản đối để đảm bảo đơn giản tránh chúng bằng thiết kế.

Đối với loại Stack của bạn, bạn có lẽ tốt nhất off xác định một interface triển khai đầu tiên và sau đó chúng (sử dụng class) để bạn không liên tục trong việc thực hiện cụ thể của Stack loại của bạn để giao diện của nó.

+1

Xác định giao diện là không cần thiết, vì có cách nhập vịt (với kiểm tra thời gian biên dịch).Ví dụ, D phạm vi có thể được sử dụng mà không có giao diện, và thường được thực hiện như cấu trúc. –

+0

@ RomanD.Boiko: Bạn đang đề cập đến các mẫu? Ngoài ra, 'giao diện' có những ưu điểm nhất định. – dirkgently

+0

Có, đối số mẫu bị hạn chế. Có lợi thế cho cả hai cách tiếp cận, tôi chỉ nói rằng việc sử dụng giao diện là không cần thiết để tránh ghép nối. –

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