2015-11-13 13 views
5

nềnSử dụng một con trỏ thông minh để quản lý cấp phát bộ nhớ trong chức năng

Nếu tôi có một hàm foo như sau

void foo(std::vector<int>& values) 
{ 
    values = std::vector<int>(10, 1); 
} 

Sau đó, tôi có thể gọi nó như

std::vector<int> values; 
foo(values); 

ý rằng số vector ban đầu trống, sau đó được điền trong hàm foo.

tôi thường đi qua các giao diện mà tôi không thể thay đổi (tức là bên thứ 3), có ý định tương tự như trên, nhưng sử dụng các mảng thô, ví dụ

void foo(int*& values) 
{ 
    values = new int[10]; 
    std::fill_n(values, 10, 1); 
} 

Vấn đề của tôi với những là bây giờ tôi chịu trách nhiệm quản lý bộ nhớ đó, vd

int* values; 
foo(values); 
delete[] values; 

Câu hỏi

Có cách nào tôi có thể sử dụng con trỏ thông minh để quản lý bộ nhớ này cho tôi? Tôi muốn làm điều gì đó như

std::unique_ptr<int[]> values; 
foo(values.get()); 

nhưng get trả về một con trỏ đó là một r có giá trị, vì vậy tôi không thể vượt qua nó bằng cách tham chiếu không const.

+1

Tôi không biết nếu điều này là hợp pháp nhưng nó biên dịch: http://coliru.stacked-crooked.com/a/860ae38fd2cdb4a2 – NathanOliver

Trả lời

2
  1. Tạo empty_ptr trống.
  2. Tạo con trỏ.
  3. Chuyển con trỏ tới hàm.
  4. Đặt lại unique_ptr cho con trỏ đó.

Giống như rằng:

std::unique_ptr<int[]> values; 
int* values_ptr; 
foo(values_ptr); 
values.reset(values_ptr); 

Hoặc:

int* values_ptr; 
foo(values_ptr); 
std::unique_ptr<int[]> values(values_ptr); 
+0

Bạn thậm chí có thể sử dụng 'make_unique' – Gabriel

+0

Coz đó là 2015 ... – Gabriel

+0

Trong thực tế make_unique xây dựng chính nó, bạn không thể cho nó một con trỏ, hoặc có thể bạn? – Gabriel

1

đơn giản trả lời: bạn không thể. Nhưng tôi tin rằng có một cách để đơn giản hóa cuộc sống của bạn. Vì bạn luôn làm điều tương tự, bạn chỉ cần viết một hàm thực hiện nó cho bạn và gọi hàm đó khi bạn cần. Vì tôi cho rằng bạn muốn sử dụng giá trị trả về được viết trong bộ nhớ trước khi phát hành nó, tôi làm cho hàm của tôi trả về nó.

template <typename T, typename Function> 
std::unique_ptr<T[]> call(Function f) { 
    T * value; 
    f(value); 
    return { value }; 
} 

// then to use it 
auto value = call<int>(foo); 

Điều đó có phù hợp với bạn không?

Chức năng có thể được cải thiện để phát hiện sự khác biệt cho con trỏ đến một đối tượng hoặc một mảng nếu bạn cần và có thể cũng được cải thiện để phát hiện tự động loại tham số cần thiết để bạn không phải nhập .

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