2009-06-04 37 views
13

Tôi đã đọc về RAII và xây dựng đơn/hai pha/khởi tạo. Vì lý do gì đó, tôi đã ở trong trại hai giai đoạn cho đến gần đây, bởi vì tại một thời điểm nào đó tôi phải nghe nói rằng nó không tốt để thực hiện các hoạt động dễ bị lỗi trong nhà xây dựng của bạn. Tuy nhiên, tôi nghĩ rằng bây giờ tôi tin rằng một pha là thích hợp hơn, dựa trên các câu hỏi tôi đã đọc trên SO và các bài viết khác.Mục tiêu C xây dựng hai pha đối tượng

Câu hỏi của tôi là: Tại sao Mục tiêu C sử dụng phương pháp hai pha (phân bổ/init) gần như dành riêng cho các nhà thầu không thuận tiện? Có bất kỳ lý do cụ thể trong ngôn ngữ, hoặc nó chỉ là một quyết định thiết kế của các nhà thiết kế?

Trả lời

28

Tôi có một tình huống tuyệt vời để làm việc cho người đã viết +alloc vào năm 1991 và tôi đã hỏi anh ấy một câu hỏi rất giống một vài tháng trước. Việc bổ sung +alloc là để cung cấp +allocWithZone:, để thêm các vùng bộ nhớ trong NeXTSTEP 2.0, nơi bộ nhớ rất chặt (4M). Điều này cho phép người gọi kiểm soát nơi các đối tượng được cấp phát trong bộ nhớ. Nó là một sự thay thế cho +new và thân nhân của nó, được (và tiếp tục được, mặc dù không ai sử dụng nó) một nhà xây dựng 1 pha, dựa trên Smalltalk's new. Khi Cocoa đến Apple, việc sử dụng +alloc đã được cố thủ, và không có quay trở lại +new, mặc dù thực sự chọn NSZone của bạn hiếm khi có giá trị đáng kể.

Vì vậy, đây không phải là câu hỏi triết học 1 pha/2 pha lớn. Trong thực tế, Cocoa có một giai đoạn xây dựng, bởi vì bạn luôn luôn làm (và luôn luôn nên) gọi những back-to-back trong một cuộc gọi duy nhất mà không có một thử nghiệm trên +alloc. Bạn có thể nghĩ về nó như một cách phức tạp để gõ "mới".

+3

+1 Ồ, tôi không thể yêu cầu câu trả lời hay hơn –

3

Trải nghiệm của tôi là với C++, nhưng một nhược điểm của việc khởi tạo một giai đoạn của C++ là xử lý các hàm thừa kế/ảo. Trong c + +, you can't call virtual functions during construction or destruction (tốt, bạn có thể, nó sẽ không làm những gì bạn mong đợi). Một giai đoạn hai init có thể giải quyết điều này (một phần. Từ những gì tôi hiểu, nó sẽ được chuyển đến lớp đúng, nhưng init có thể chưa kết thúc. Bạn vẫn có thể làm được điều đó) (Tôi vẫn ủng hộ một pha)

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