簡體   English   中英

為什么“vector.erase()”(在 C++ 中)沒有按預期運行?

[英]Why "vector.erase()" (in C++) is not behaving as expected?

我寫了一個簡單的程序來測試“vector.erase”功能。 有一個簡單的 class (MyClass0),它在其構造函數和析構函數中寫入一些相關消息。 然后是一個向量,其中包含 4 個 MyClass0 類型的對象。 當我擦除向量的第二個元素時:

    vec0.erase(vec0.begin() + 1);

我想應該在屏幕上輸出消息“GoodBye From 2”。 但是顯示消息“GoodBye From 4”。 似乎調用了向量的第 4 個元素的析構函數。 (盡管並非如此,因為當“main”完成時,第 4 個元素將在最后被破壞)。 任何人都可以幫助我,以便我找出原因。 屏幕上顯示的代碼和 output 是:

代碼:

#include <iostream>
#include <vector>

using std::cout;
using std::endl;

class MyClass0
{
public:
    MyClass0(int i_i_) : i_(i_i_)
    {
        cout << "Hello From " << this->i_ << endl;
    }
    ~MyClass0()
    {
        cout << "GoodBye From " << this->i_ << endl;
    }
    std::string MyToString()
    {
        return std::string("This is ") + std::to_string(this->i_);
    }
private:
    int i_;
};


int main()
{
    std::vector<MyClass0> vec0 = { MyClass0(1), MyClass0(2), MyClass0(3), MyClass0(4) };
    cout << endl << "Before erasing..." << endl;
    vec0.erase(vec0.begin() + 1);
    cout << "After erase" << endl << endl;

    return 0;
}

屏幕上的Output:

Hello From 1
Hello From 2
Hello From 3
Hello From 4
GoodBye From 4
GoodBye From 3
GoodBye From 2
GoodBye From 1

Before erasing...
GoodBye From 4
After erase

GoodBye From 1
GoodBye From 3
GoodBye From 4

https://godbolt.org/z/qvrcb81Ma

她是你的代碼修改了一下

class MyClass0
{
public:
    MyClass0(int i_i_) : i_(i_i_)
    {
        cout << "Hello From " << this->i_ << endl;
    }
    ~MyClass0()
    {
        cout << "GoodBye From " << this->i_ << endl;
    }
    std::string MyToString()
    {
        return std::string("This is ") + std::to_string(this->i_);
    }
    MyClass0(const MyClass0& other) : i_{other.i_}
    {
        std::cout << "Copy construct " << i_ << '\n';
    }

    MyClass0& operator=(const MyClass0& other)
    {
        std::cout << "Asign " << other.i_ << " onto " << i_ << '\n';
        i_ = other.i_;
        return *this;
    }
private:
    int i_;
};

什么暴露了實際發生的事情: https://godbolt.org/z/hW177M7o6

當 vector 從中間刪除項目時,它使用operator=將項目分配給左側,然后刪除最后一個項目。

矢量不允許在中間有任何孔。 這意味着當您刪除第二個元素時,您實際上並沒有刪除它。 發生的情況是所有元素都向前移動以填充孔,之后向量中的最后一個元素可以被刪除,因為它已經向前移動了一次

//start with
1 2 3 4

// erase 2, so move 3 into 2 and 4 into 3
1 3 4 *

// * is old 4 and we don't need that so remove it from the collection
1 3 4

// removing * calls the destructor for that element

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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