簡體   English   中英

定義運算符重載時擦除向量的 object 元素時出錯

[英]Error when erasing an object element of a vector when operator overloading is defined

在下面的簡單示例程序中,我有一個對象向量t_cell ,我用 5 個元素對其進行了初始化。 我還有一個整數測試向量。

#include <iostream>
#include <iomanip>
#include <vector>

using namespace std;

class t_cell {
    public:
        int id;

    t_cell operator = ( const t_cell &rhs_cell ){
        t_cell lhs_cell;
        lhs_cell.id = rhs_cell.id;
        return lhs_cell;
    }
};


int main(){

    std::vector<int   > test ( 5 );
    std::vector<t_cell> cells( 5 );

    for( size_t icell=0; icell < cells.size(); icell++ ){
        test [icell]    = icell;
        cells[icell].id = icell;
    }

    for( size_t icell=0; icell < cells.size(); icell++ ){
        cout << "before =" << icell << test [icell] << cells[icell].id << endl;
    }
    cout << endl;

    // Erase
    cells.erase( cells.begin() + 3 );
    test .erase( test .begin() + 3 );

    for( size_t icell=0; icell < cells.size(); icell++ ){
        cout << "after  =" << icell << cells[icell].id << test [icell] << endl;
    }

    return 0;
}

擦除元素適用於 integer 向量,但不適用於對象向量:

before =000
before =111
before =222
before =333
before =444

after  =000
after  =111
after  =222
after  =334

循環索引表明向量的大小已減小(現在僅從 0 變為 3)。 但是,第三個元素的id沒有被正確擦除。

我發現問題來自運算符重載定義。 刪除按預期工作:

before =000
before =111
before =222
before =333
before =444

after  =000
after  =111
after  =222
after  =344

GCC 8.3.1 和 10.1.0 產生相同的行為。 我已經編譯了沒有標志的代碼。

operator=的目的是更改*this以匹配操作數的 state ,然后返回對*this的引用,但這不是您正在做的 - 相反,您正在創建一個值並返回它。 返回的值被調用者立即丟棄,因此調用操作符對程序的 state 沒有任何明顯的影響。

更改您的代碼以改變*this並返回對自身的引用:

t_cell & operator = ( const t_cell &rhs_cell ){
    id = rhs_cell.id;
    return *this;
}

當然,在這種情況下,您的 class 是隱式可復制的,因為所有成員都是可復制的。 您可以簡單地不定義operator=並且編譯器會為您生成一個合適的,這將與我上面顯示的運算符完全相同。

暫無
暫無

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

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