2015-05-17 19 views
11

Tôi có một hàm cần trả về một con trỏ tới một đối tượng của lớp myClass. Vì mục đích này, tôi đang sử dụng std::unique_ptr.C++ std :: unique_ptr trở về từ hàm và kiểm tra cho null

Nếu hàm thành công, nó sẽ trả về một con trỏ tới một đối tượng có dữ liệu. Nếu không thành công, nó sẽ trả lại null.

Đây là mã skelepton tôi:

std::unique_ptr<myClass> getData() 
{ 
    if (dataExists) 
     ... create a new myClass object, populate and return it ... 

    // No data found 
    return std::unique_ptr<myClass> (null); <--- Possible ? 
} 

trên main:

main() 
{ 
    std::unique_ptr<myClass> returnedData; 

    returnedData = getData(); 

    if (returnedData != null) <-- How to test for null ? 
    { 
     cout << "No data returned." << endl; 
     return 0; 
    } 

    // Process data 
} 

Vì vậy, ở đây đi câu hỏi của tôi:

a) Là (trả lại một đối tượng hoặc null) thể được thực hiện bằng cách sử dụng std::unique_ptr?

b) Nếu có thể, cách triển khai?

c) Nếu không thể, lựa chọn thay thế là gì?

Cảm ơn bạn đã trợ giúp.

+1

Tạo một con trỏ duy nhất là 'std :: unique_ptr myptr;' không cấp phát bất kỳ bộ nhớ nào, do đó bạn không cần phải xây dựng nó và vượt qua 'nullptr'. Vì vậy, bạn chỉ có thể tạo một và trả lại. – AndyG

+1

'nullptr' là từ khóa mới trong C++ 11 để hỗ trợ tốt hơn các con trỏ null. 'unique_ptr' có thể được xây dựng từ' nullptr', thậm chí ngầm. – dyp

Trả lời

19

Hoặc những điều sau đây nên làm việc:

return std::unique_ptr<myClass>{}; 
return std::unique_ptr<myClass>(nullptr); 

Để kiểm tra xem các trở đối tượng trỏ đến một đối tượng hợp lệ hay không, chỉ cần sử dụng:

if (returnedData) 
{ 
    // ... 
} 

Xem http://en.cppreference.com/w/cpp/memory/unique_ptr/operator_bool.

+1

Kiểm tra kết quả sẽ giống như 'if (returnData! = Std :: nullptr)'? – Mendes

+1

@Mendez, hãy xem cập nhật cho câu trả lời của tôi –

+2

Chỉ cần 'return nullptr;' cũng sẽ hoạt động. –

6

Có thể. Mặc định được xây dựng unique_ptr là những gì bạn muốn:

Xây dựng một std::unique_ptr không có gì.

// No data found 
return std::unique_ptr<myClass>{}; 

Đó là tương đương với các nhà xây dựng nullptr_t, vì vậy có lẽ đây là rõ ràng hơn:

// No data found 
return nullptr; 
2

Có, điều đó là có thể.

Từ trang tài liệu tham khảo std::unique_ptr::unique_ptr():

constexpr unique_ptr();

xây dựng một std::unique_ptr sở hữu gì cả.

Vì vậy, về cơ bản:

std::unique_prt<myClass> getData() 
{ 
    myClass* data_ptr = nullptr; 

    if (dataExists) 
     // Create a new myClass object, populate and store in 'data_ptr' 

    return std::unique_ptr<myClass>(data_ptr); //'data_ptr' is either valid pointer or nullptr 
} 

Đối với séc vô hiệu, sử dụng std::unique_ptr::operator bool - chỉ đơn giản là sử dụng nó như điều kiện bên trong if tuyên bố:

main() 
{ 
    std::unique_ptr<myClass> returnedData = getData(); 

    if (returnedData) 
    { 
     // Data OK - Process 
    } 

} 

Là trang tài liệu tham khảo cho std::unique_ptr::operator bool nói:

Kiểm tra s cho dù *this sở hữu một đối tượng, tức là get() != nullptr.

+1

Tôi sẽ tránh sử dụng con trỏ thô sở hữu như 'data_ptr' ngay cả khi nó chỉ sở hữu một dòng. Lưu trữ trong một 'unique_ptr' trực tiếp. –

3

Có, điều đó là có thể. Một mặc định xây dựng unique_ptr hoặc một trong xây dựng từ nullptr có thể bị coi là vô:

std::unique_ptr<MyClass> getData() 
{ 
    if (dataExists) 
     return std::make_unique<MyClass>(); 
    return nullptr; 
} 

Để kiểm tra cho null hoặc so sánh với nullptr hoặc tận dụng chuyển đổi sang bool:

int main() 
{ 
    std::unique_ptr<MyClass> returnedData = getData(); 

    if (returnedData) 
    { 
     ... 
    } 
} 
1

Trong C mới nhất ++ thư viện có phải là một hàm make_unique trong <memory> cho phép chúng tôi thực hiện unique_ptr dễ dàng như trong thư viện C++ 11 cho phép với make_shared và các con trỏ được chia sẻ.

Vì vậy, bạn có thể làm sáng tỏ các mã một chút bằng cách quay std::make_unique(nullptr)

Plus trong phiên bản tiếp theo của C++ sẽ có một "lựa chọn" kiểu đó sẽ đánh giá như một trong hai giá trị some hoặc một giá trị none. Giá trị none sẽ không được phép coi là giá trị hợp lệ, không giống như unique_ptr trống có thể được xử lý như một nullptr. Kiểu tùy chọn sẽ đại diện cho một phần khác của Boost vào thư viện chuẩn.

+1

Yup, 'boost :: optional'. Có tài liệu nào cho thấy sự chấp nhận của nó vào C++ 17 không? Chỉnh sửa: Tôi đoán điều này sẽ làm: http://en.cppreference.com/w/cpp/utility/optional –

+1

@underscore_d Tại [this] (https://meetingcpp.com/index.php/br/items/ c17-library-paper-for-cologne.html) giấy N có vẻ là N4270, mặc dù phiên bản liên kết thực tế của giấy có vẻ thô ráp (hoặc "drafty" chúng ta sẽ nói?) –

+0

Tuyệt vời, cảm ơn thông tin! Tôi đã không nghe nói về điều này được kết hợp cho đến bây giờ ... hoặc nếu tôi đã nghe, sau đó tôi ngay lập tức quên. –

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