2011-11-23 18 views
5

Tôi đang trong quá trình chuyển một số mã từ Mục tiêu C sang C++. Tôi không phải là quen thuộc với các mẫu thiết kế C++ như tôi với Objective C. Trong thế giới ca cao, có một mô hình rất phổ biến của việc viết một phương thức factory trả về một đối tượng "autoreleased". Những điều đơn giản như:Mục tiêu C "autorelease" trong C++ - cách tiêu chuẩn để kiểm soát tuổi thọ đối tượng?

- (MyClass *)load { 

    MyClass* obj = [[MyClass alloc] init]; 
    return [obj autorelease]; 
} 

Điều này rất đơn giản và dễ hiểu. Phương thức này sở hữu bộ nhớ mà nó phân bổ, nhưng có thể trao lại cho người gọi, đồng thời từ bỏ quyền sở hữu. Nó không phải biết hoặc quan tâm những gì người gọi làm với bộ nhớ đó. Nếu nó giữ lại nó, vật thể sẽ tồn tại. Nếu nó hoàn toàn bị bỏ qua, bộ nhớ sẽ được giải phóng đôi khi sau khi stack cuộc gọi hiện tại là unwound.

Tôi đang tiếp cận điều này với một số lo ngại trong C++, vì môi trường không được tính lại của nó dường như không có bất kỳ thứ gì sạch sẽ như autorelease hoặc bất kỳ loại chính sách quyền sở hữu nào được xác định rõ ràng Khung cacao. Các phương pháp hay nhất cho loại mẫu này trong C++ là gì?

Tôi biết về auto_ptr, nhưng cũng có rất nhiều mối quan tâm với việc sử dụng nó và có vẻ như có quá nhiều thiếu sót ở khắp mọi nơi như autorelease (ngữ nghĩa sao chép lạ, không hỗ trợ mảng, không tương thích với vùng chứa STL , v.v.)

Boost con trỏ thông minh cũng là một ứng cử viên rõ ràng, và một số thậm chí thực hiện tính tham khảo riêng của họ. Có vẻ hơi lạ khi tôi phải dựa vào một thư viện của bên thứ ba cho thứ gì đó trần tục này.

Một tùy chọn khác mà reeks của C sẽ chỉ là không giải phóng bộ nhớ đã trả về, nhưng cho biết thông qua quy ước đặt tên thông thường mà người gọi hiện đang sở hữu đối tượng được trả về. Điều này có vẻ hơi cổ xưa, và dễ bị rò rỉ vô hình nên người gọi vô tình bỏ qua giá trị trả về.

+2

"Có vẻ như hơi lạ khi tôi phải dựa vào thư viện của bên thứ ba cho thứ gì đó trần tục này." Làm quen với nó. Đó là cách mọi thứ được thực hiện trong C++: bạn tìm thấy các thư viện làm những gì bạn cần, và bạn sử dụng chúng. Quyền sở hữu trí nhớ không phải là cú pháp trong C++; đó là * luôn luôn * thủ công. –

Trả lời

8

"Các phương pháp hay nhất" trong thế giới C++ 03 (nghĩa là, pre-C++ 11) là một trong hai điều sau:

  1. Không làm gì cả. Đây chủ yếu là quyền sở hữu trí nhớ theo giả định/quy ước. Nếu một hàm trả về một con trỏ, bạn nên biết ai sở hữu nó. Thông thường, tài liệu sẽ cho bạn biết. Không có cú pháp cụ thể cho quyền sở hữu bộ nhớ hoặc chuyển quyền sở hữu.

    Đây là cách một số lượng lớn mã C++ không may ngoài đó quản lý bộ nhớ. Nó có thể hoạt động, miễn là mọi người đều biết họ nên làm gì và ai chịu trách nhiệm cho cái gì.

  2. Sử dụng một số hình thức của con trỏ thông minh. std::auto_ptr là lẻ, nhưng đó là về trọng lượng nhẹ như nó được trong C + + 03. Không, bạn không thể dán chúng vào các thùng chứa tiêu chuẩn, nhưng nó xác định một mẫu quyền sở hữu cụ thể.Một boost::shared_ptr là một cái hiệu quả hơn, và hữu dụng hơn ở nhiều nơi khác.

C++ 11 Mời std::unique_ptr, mà thực chất là một "cố định" auto_ptr. Nó dựa trên các tính năng ngôn ngữ C++ 11 (chuyển động đối tượng), vì vậy bạn không thể chỉ viết một trong C++ 03. Bạn có thể lưu trữ chúng trong các thùng chứa tiêu chuẩn và mọi thứ. Nhưng bạn không thể vượt qua chúng. Như tên cho thấy, chúng là duy nhất: chỉ một trong số chúng có thể tồn tại trỏ đến đối tượng đó. Khi unique_ptr bị phá hủy, nó sẽ xóa đối tượng mà nó tham chiếu.

Bạn có thể chuyển quyền sở hữu unique_ptr chỉ bằng cách cho đi. Tức là, bạn không thể chia sẻ quyền sở hữu. Bạn có thể trả lại quyền sở hữu, có nghĩa là người gọi hiện đang sở hữu nó. Bạn có thể chuyển quyền sở hữu cho một hàm khác, có nghĩa là hàm đó sở hữu nó. Nhưng không có hai thực thể nào có thể sở hữu một đối tượng thông qua một unique_ptr.

unique_ptr sẽ là phương pháp ưu tiên xử lý một chức năng như thế này. Nếu người dùng muốn lưu trữ nó không phải là duy nhất, thì họ có thể phát hành nó thành một std::shared_ptr (cũng được chấp nhận vào C++ 11).

3

Tôi sẽ xem xét tăng số shared_ptr.

Thế giới C++ là tất cả về thư viện. Bởi vì không có ai sở hữu C++ (không giống như Objective-C), nó phát triển khi cộng đồng thấy sự cần thiết.

2

Vâng c nhất ++ - như tùy chọn là sử dụng con trỏ thông minh ..

Từ những gì tôi đọc, con trỏ tính tham khảo là đặt cược tốt nhất của bạn, trong tiêu chuẩn C++ 11 bạn có thể sử dụng shared_ptr