簡體   English   中英

使用unique_ptr成員返回對象需要什么?

[英]What do I Need to Return an Object with a unique_ptr Member?

讓我們說我有這個對象:

struct foo {
    std::unique_ptr<int> mem;
    virtual ~foo() = default;
};

我不能再返回在函數中創建的foo對象:

foo make_foo() {
    foo result;

    result.mem = std::make_unique<int>({});
    return result;
}

可能表明我需要析構函數是虛擬的,因為這將是一個基類。 但即使我使用默認的析構函數,這還不夠,我仍然無法返回函數中創建的對象。

我收到錯誤:

error C2280: foo::foo(const foo &): attempting to reference a deleted function

有沒有辦法解決這個問題?

Per [class.copy.ctor] / 8

如果類X的定義沒有顯式地聲明一個移動構造函數,那么當且僅當[...]時,非顯式的一個將被隱式聲明為默認值。

  • X沒有用戶聲明的析構函數。

以來

virtual ~foo() = default;

是一個用戶聲明的析構函數,你不再有一個移動構造函數,所以它試圖使用復制構造函數,但不能,因為你有一個不可復制的成員刪除它。

要恢復移動構造函數,並保持默認構造,您需要添加

foo() = default;
foo(foo&&) = default;
foo &operator=(foo &&) = default; // add this if you want to move assign as well

foo


你必須添加foo() = default; 當你添加foo(foo&&) = default; foo(foo&&) = default; 是一個用於聲明的構造函數,如果您有任何用戶聲明的構造函數,則不再提供默認構造函數。


這是一個“黑客”,但你可以做的是將虛擬析構函數移動到另一個類,然后從中繼承。 這將為您提供foo的虛擬析構函數,而無需聲明它並為您提供所需的默認構造函數。 那看起來像

struct make_virtual
{
    virtual ~make_virtual() = default;
};

struct foo : make_virtual {
    std::unique_ptr<int> mem;
};

提供您自己的復制構造函數和默認構造函數,將成員轉換為共享指針或提供移動構造函數。 一種可能的方案:

struct foo {
    unique_ptr<int> mem;
    foo() = default;
    foo(const foo& copy);
    virtual ~foo() = default;
};

foo::foo(const foo& copy) : mem(new int(*copy.mem)) {}

foo make_foo() {
    foo result;
    result.mem = make_unique<int>();
    return result;
}

暫無
暫無

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

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