[英]Why doenst STL vector call default constructor on allocation?
我得到了以下代碼塊:
#include <vector>
#include <iostream>
struct TestStruct {
bool wasCreated;
TestStruct() {
std::cout << "Default Constructor" << std::endl;
wasCreated = false;
}
~TestStruct() {
if (wasCreated) {
DoImportantStuff();
}
}
void Create() {
wasCreated = true;
}
// delete all copy stuff
TestStruct(const TestStruct&) = delete;
TestStruct& operator=(const TestStruct&) = delete;
// implement only move assignment & ctor
TestStruct(TestStruct&& other) {
std::swap(wasCreated, other.wasCreated);
}
TestStruct& operator=(TestStruct&& other) {
std::swap(wasCreated, other.wasCreated);
return *this;
}
// very important stuff
void DoImportantStuff() {
std::cout << "Do Important Stuff" << std::endl;
}
};
int main() {
std::vector<TestStruct> testVector;
testVector.emplace_back(TestStruct());
testVector.emplace_back(TestStruct());
std::cin.get();
}
此代碼導致輸出:
默認構造函數
做重要的東西
默認構造函數
做重要的東西
做重要的東西
基本上我想寫一個類,它擁有內存但只在我調用Create()
時才分配這個內存。 為了避免內存泄漏並避免刪除未分配的內存,我引入了wasCreated
,這只有在調用Create()
時才會wasCreated
。 每個TestStruct都應保存在一個向量中。 所以在實施移動分配&ctor並刪除了復制分配和ctor。
現在在我看來,當我的TestStruct分配新內存時,向量doenst會調用我的TestStruct的默認構造函數。 為什么會這樣,如何讓向量在內存分配上調用默認構造函數? 我需要自己的分配器嗎?
您的問題是您的移動構造函數實現不正確。 它在新創建的對象和正在移動的對象之間交換wasCreated
,但新創建的對象中的變量尚未初始化 (默認構造的bool具有未知值)。 因此,使用TestStruct()
創建的臨時對象會收到一個未初始化的bool,在您的情況下恰好是true
,因此在它們的析構函數中調用DoImportantStuff()
。
所以移動構造函數應該看起來像這樣:
// implement only move assignment & ctor
TestStruct(TestStruct&& other) : wasCreated(other.wasCreated) {
other.wasCreated = false;
}
(您已將所有權移至新創建的對象,舊的對象不再擁有任何內容。)
不要將賦值運算符與構造函數混淆; 他們做不同的事情。 賦值運算符處理兩個已經構造的對象; 在構造函數的情況下,正在構造的對象是......,還沒有構造,因此它沒有有效的狀態。
順便說一句, emplace_back()
與你使用它的方式毫無意義。 其目的是將其參數直接轉發給向量內對象的構造函數。 由於您有默認構造函數(無參數),因此調用應為:
testVector.emplace_back();
這將默認構建TestStruct
。
現在在我看來,當我的TestStruct分配新內存時,向量doenst會調用我的TestStruct的默認構造函數。
默認構造的向量大小為零,因此沒有要構造的對象。
如果您希望向量默認構造一些對象,請調整其大小。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.