簡體   English   中英

為什么doenst STL vector會在分配時調用默認構造函數?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM