[英]std::list< std::unique_ptr<T> >: passing it around
假設我有一個class T
的std::list
:
std::list<T> l;
將它傳遞給函數時,我會使用引用:
someFunction( std::list<T> &l )
傳遞一個std::list
unique_ptr
std::list
的最佳方法是什么?
std::list< std::unique_ptr<T> > l;
像這樣:
someFunction( std::unique_ptr<T> ptr )
或這個:
someFunction( T* ptr )
或這個:
someFunction( T &ref )
那么如何使用std::list
的back()
函數調用它呢? 這些是恕我直言所有“類型”相當,但我敢肯定我在這里遺漏了一些東西。
謝謝
為了最好的情況:
第一個是最好的,因為它不會修改它的對象,無論你如何分配它都可以使用它(例如,你可以毫無問題地切換到shared_ptr)。
無論你使用什么智能指針,第二個也會工作; 但是,它假設您可以修改對象,並且只要您可以創建const,就應該。
數字3和4都允許指向的對象發生變異; 但是,#3不允許修改智能指針,而數字4則允許。 兩者都有缺點,它們強制使用unique_ptr,而上面的兩個都可以工作,無論智能指針類。
按值傳遞unique_ptr,就像在其他一些示例中一樣,不是一個選項; unique_ptr應該是唯一的。 如果要復制它,請考慮使用shared_ptr。
對於前兩個,如果你在back()的結果上調用它,它看起來像:
someFunction(*(lst.back())); // dereference lst.back() before passing it in.
對於后兩者,如果你在back()的resut上調用它,它看起來像:
someFunction(lst.back()); // pass the smart pointer, not the object to
// which the smart pointer currently points.
不及格unique_ptr
的價值,首先它不會編譯沒有std::move
,如果你使用std::move
將清空您已存儲在您的值list
,你將無法訪問它了。
這是因為unique_ptr
不可復制,它沒有unique_ptr::unique_ptr(const unique_ptr<T>& other)
類型的復制構造函數unique_ptr::unique_ptr(const unique_ptr<T>& other)
而只有一個移動構造函數( unique_ptr::unique_ptr(unique_ptr<T>&& source)
)。
unique_ptr以及包含unique_ptr的類/實例可以在std :: list(和其他容器)中使用,前提是它們已經定義了移動構造函數 class_name(class_name &&)
(當然,unique_ptr有)。
當你傳遞這些元素時,你總是移動(而不是復制)它們,所以你總是在左值上使用std :: move(),就像在
my_list.push_back(std::move(my_element));
這使得您可以看到您將元素傳遞(=移動)到列表中,並且在該操作之后my_element為“空”(如空unique_ptr)。
例:
typedef std::unique_ptr<uint8_t[]> data_ptr;
class data_holder
{
private:
int something_about_data;
data_ptr data;
public:
data_holder(data_ptr && _data)
: data(std::move(_data))
{}
// hey compiler, please generate a default move constructor for me
// despite of present destructor
data_holder(data_holder &&) = default;
~data_holder()
{
// ...
}
bool is_empty() const { return ! bool(data); }
}
// ...
{
// ...
data_holder the_element(data_ptr(new uint8_t[DATA_SIZE]));
// move the_element into the_list
the_list.push_back(std::move(the_element));
if (the_element.is_empty())
std::cerr << "data_holder 'the_element' is now empty!" << std::endl;
// ...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.