我明白,如果你要傳遞MyClass的對象的載體,它是一個臨時變量,如果有一個MyClass的定義,那麼此舉的構造,這將被調用,但如果你通過時會發生什麼矢量boost::shared_ptr<MyClass>
或std::shared_ptr<MyClass>
? shared_ptr是否有一個移動構造函數,然後調用MyClass的移動構造函數?移動構造函數的shared_ptr的矢量<MyClass>
回答
如果存在用於MyClass的定義,那麼這將被稱爲
一般不是一個移動構造函數。移動矢量通常是在我轉移託管數組的所有權的情況下完成的,將移出的矢量留空。物體本身沒有被觸摸。 (我認爲如果這兩個向量具有不兼容的分配器,可能會有例外,但這超出了我需要處理的任何事情,所以我不清楚那裏的細節)。
shared_ptr是否有一個移動構造函數,然後調用MyClass的移動構造函數?
不需要。它還有一個移動構造函數,它將MyClass
對象的所有權轉移給新指針,並將舊指針留空。對象本身是未觸及的。
是的,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);
如果你的意思是移動std::vector<std::shared_ptr<MyClass>>
。那麼即使移動構造函數std::shared_ptr
也不會被調用。因爲移動操作直接在std::vector
級完成。
例如,std::vector<T>
可以實現爲指向數組T
和size
成員的指針。
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()));
}
在這種代碼的操作是顯而易見的:如果兩個this
和right
操作數具有相同的分配器,它將直接盜取內容而不對每個元素執行任何操作。但是如果他們沒有,那麼移動個體元素的操作就會被調用。在這個時候,其他答案適用(對於std::shared_ptr
東西)。
我以爲每個元素都移動了嗎? – user997112
@ user997112,我很懷疑。 – Shoe
- 1. 爲什麼shared_ptr <T>期望T中的複製/移動構造函數?
- 2. 如何正確處理移動構造函數的shared_ptr映射?
- 3. 目的的shared_ptr <T> &&作爲構造函數參數的
- 4. C++:初始化shared_ptr的矢量在構造函數不同的指針
- 5. shared_ptr的拷貝構造函數裏面
- 6. 傳遞矢量<shared_ptr的<Derived>>到功能期待矢量<shared_ptr的<Base>>
- 7. 移動構造函數C++
- 8. 與移動構造函數
- 9. 的shared_ptr <T>到shared_ptr <T const>和矢量<T>到矢量<T const>
- 10. 矢量 - push_back使用默認的構造函數不復制構造函數
- 11. 移動構造函數不移動
- 12. 移動構造函數並移動類
- 13. shared_ptr的矢量與
- 14. 向量移動構造函數比複製構造函數要慢
- 15. C++向量執行 - 移動構造函數 - 移動VS向前
- 16. 與移動構造函數混淆:無法調用移動構造函數
- 17. std :: shared_ptr <X>有複製構造函數嗎?
- 18. 將std :: shared_ptr傳遞給構造函數
- 19. Move構造函數調用基類移動構造函數
- 20. 移動構造函數和非常拷貝構造函數
- 21. 如何從矢量<shared_ptr>
- 22. 在矢量構造
- 23. 使用矢量構造函數分配動態內存
- 24. 瞭解移動構造函數,的std ::移動和析構函數
- 25. C++傳遞的std ::矢量<提高:: shared_ptr的< foo >>
- 26. 類的矢量的shared_ptr的類的析構函數導致錯誤
- 27. C++ - 構造函數,複製構造函數,移動構造函數,析構函數
- 28. C++當函數返回矢量<shared_ptr<>>時會發生什麼?
- 29. 使用構造函數的參數初始化矢量成員
- 30. 函數參數:矢量<Clazz*>&VS矢量<Clazz>&
它具有常規移動構造函數以及模板,因爲模板不能用作移動或複製構造函數。 –
@MikeSeymour:參考? –
C++ 11 20.7.2.2 for'shared_ptr'。更一般地,12.8/3:「類X的A **非模板**構造函數是一個移動構造函數,如果...」 –