2013-11-27 41 views
1

我明白,如果你要傳遞MyClass的對象的載體,它是一個臨時變量,如果有一個MyClass的定義,那麼此舉的構造,這將被調用,但如果你通過時會發生什麼矢量boost::shared_ptr<MyClass>std::shared_ptr<MyClass>? shared_ptr是否有一個移動構造函數,然後調用MyClass的移動構造函數?移動構造函數的shared_ptr的矢量<MyClass>

回答

3

如果存在用於MyClass的定義,那麼這將被稱爲

一般不是一個移動構造函數。移動矢量通常是在我轉移託管數組的所有權的情況下完成的,將移出的矢量留空。物體本身沒有被觸摸。 (我認爲如果這兩個向量具有不兼容的分配器,可能會有例外,但這超出了我需要處理的任何事情,所以我不清楚那裏的細節)。

shared_ptr是否有一個移動構造函數,然後調用MyClass的移動構造函數?

不需要。它還有一個移動構造函數,它將MyClass對象的所有權轉移給新指針,並將舊指針留空。對象本身是未觸及的。

3

是的,std::shared_ptr<T>有一個移動構造函數,以及一個模板化的構造函數,它可以從相關的共享指針移動,但根本不觸碰管理對象。新構造的共享指針共享被管理對象的所有權(如果有的話),並且移出的指針將被分離(「null」)。

實施例:

struct Base {};    // N.B.: No need for a virtual destructor 
struct Derived : Base {}; 

auto p = std::make_shared<Derived>(); 
std::shared_ptr<Base> q = std::move(p); 

assert(!p); 
+0

它具有常規移動構造函數以及模板,因爲模板不能用作移動或複製構造函數。 –

+0

@MikeSeymour:參考? –

+0

C++ 11 20.7.2.2 for'shared_ptr'。更一般地,12.8/3:「類X的A **非模板**構造函數是一個移動構造函數,如果...」 –

3

如果你的意思是移動std::vector<std::shared_ptr<MyClass>>。那麼即使移動構造函數std::shared_ptr也不會被調用。因爲移動操作直接在std::vector級完成。

例如,std::vector<T>可以實現爲指向數組Tsize成員的指針。

template <typename T> 
class vector { 
public: 
    /* ... other members */ 
    vector(vector &&another): _p(another._p), _size(another._size) { 
     /* Transfer data ownership */ 
     another._p = nullptr; 
     another._size = 0; 
    } 

private: 
    T *_p; 
    size_t _size; 
} 

你可以在這個過程中看到,T類型的沒有數據成員被觸摸的所有:可以爲實現這一此舉構造函數。

編輯:更特別在C++ 11標準:§23.2.1。一般容器要求(4)有一個表包含關於一般的容器的實施方案的要求,它包含下列要求:

X是元素的類型,u是一個標識符聲明,rv是右值引用,a是)X類型的容器

X u(rv) 
X u = rv 

C++標準:這兩個(移動構造函數)應該對所有的標準容器恆定時間複雜除了std::array

所以很容易得出結論,實現必須使用像我上面指出的移動構造函數std::vector的方式,因爲它無法調用單個元素的移動構造函數,或者時間複雜度將成爲線性時間。

a = rv 

C++標準:的a所有現有的元素是移動分配給或破壞一個應等於該值,該值rv該分配過的。

這是移動賦值運算符。這句話只說明a中的原始元素應該被「正確處理」(移動分配或被銷燬)。但這不是一個嚴格的要求。恕我直言的實施可以選擇最適合的方式。

我還研究了代碼在Visual C++ 2013,這是我發現片斷(vector頭,從管線836開始):

/* Directly move, like code above */ 
void _Assign_rv(_Myt&& _Right, true_type) 
{ // move from _Right, stealing its contents 
    this->_Swap_all((_Myt&)_Right); 
    this->_Myfirst = _Right._Myfirst; 
    this->_Mylast = _Right._Mylast; 
    this->_Myend = _Right._Myend; 

    _Right._Myfirst = pointer(); 
    _Right._Mylast = pointer(); 
    _Right._Myend = pointer(); 
} 

/* Both move assignment operator and move constructor will call this */ 
void _Assign_rv(_Myt&& _Right, false_type) 
{ // move from _Right, possibly moving its contents 
    if (get_allocator() == _Right.get_allocator()) 
     _Assign_rv(_STD forward<_Myt>(_Right), true_type()); 
    else 
     _Construct(_STD make_move_iterator(_Right.begin()), 
     _STD make_move_iterator(_Right.end())); 
} 

在這種代碼的操作是顯而易見的:如果兩個thisright操作數具有相同的分配器,它將直接盜取內容而不對每個元素執行任何操作。但是如果他們沒有,那麼移動個體元素的操作就會被調用。在這個時候,其他答案適用(對於std::shared_ptr東西)。

+1

我以爲每個元素都移動了嗎? – user997112

+0

@ user997112,我很懷疑。 – Shoe

相關問題