簡體   English   中英

為什么在函數內部初始化時 C++ 對象會被破壞? 我能做些什么來防止它?

[英]Why are C++ objects destroyed when initialized inside function? What can I do to prevent it?

在這里,當我推入堆棧時,為什么對象會被銷毀?

#include <iostream>
#include <stack>

class One
{
private:
        int i;
public:
        One(int i) {this->i = i;}
        ~One() {std::cout << "value " << this->i << " is destroyed\n";}
};

int main()
{
        std::stack<One> stack;
        stack.push(One(1));
        stack.push(One(2));

        std::cout << "Now I'll stop\n";
}

我希望之前看不到任何輸出Now I'll stop 但我明白了

value 1 is destroyed
value 2 is destroyed
Now I'll stop
value 1 is destroyed
value 2 is destroyed

如果我想防止它們被破壞,我該怎么辦?

One(1)One(2)構造兩個臨時對象,將它們傳遞給push然后復制(移動)到stack 臨時表在完整表達式后立即銷毀。

如果您想避免構建臨時文件,您可以改用emplace

將一個新元素壓入堆棧頂部。 該元素是就地構造的,即不執行復制或移動操作。

例如

stack.emplace(1);
stack.emplace(2);

讓我在宋元瑤的答案中添加一個說明細節來解決實際問題。

如果向One類添加復制構造函數,您將更容易理解發生了什么以及如何保持創建和銷毀之間的平衡。 (對你來說,兩個創造物獲得 4 次破壞是不是很神奇?)

只要您不定義(或提及)復制構造函數,編譯器就會為您創建一個具有簡單實現復制構造函數,該實現對所有成員進行按位復制。 因此,在您的情況下,您觀察到的行為可能令人困惑,但並沒有做任何特別糟糕的事情。 這當然會在您添加涉及不僅僅是復制的成員時立即改變,例如指向必須在某處銷毀的成員的指針......

在下面的示例中,我向兩個構造函數都添加了輸出,並且還從在構造函數體中分配成員切換到了初始化列表

class One
{
  public:
    One(int rhs): i(rhs) {
        std::cout<< "value " << i << " was created from int\n";
    }
    One(const One& rhs): i(rhs.i) {
        std::cout<< "value " << i << " was created by copy\n";
    }
    ~One() {
        std::cout << "value " << i << " is destroyed\n";
    }

  private:
    int i;
};

當你這樣做時stack.push(One(1)); 它創建了一個名為One(1) rvalue 的臨時對象,然后將其復制到 Stack。 所以在復制之后,臨時對象會被銷毀。

暫無
暫無

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

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