簡體   English   中英

從派生復制構造函數調用基類的移動構造函數

[英]Calling base's move constructor from derived copy constructor

我是新來的,所以如果我需要改變任何東西,請告訴我。 我盡我所能做到徹底並提供示例代碼。 我知道有人問過很多類似的問題,但我找不到與我的具體問題相符的問題。

此外,我知道我正在做的不是在“真實”代碼中會做的事情,我只是想更好地理解 r/l/p/x..values。

我有一個基類和一個派生類,都具有默認、復制和移動構造函數。 現在我想讓派生類的復制構造函數調用基類的移動構造函數。

class Base
{
public:
    Base(){ std::cout << "default base constructor called.\n"; }

    Base(Base const &other) { std::cout << "copy base constructor called.\n"; }

    Base(Base &&tmp) { std::cout << "move base constructor called.\n"; }
};

派生類基本相同:

class Derived : public Base
{
public:
    Derived(){ std::cout << "default derived constructor called.\n";}

    Derived(Derived const &other)
    :
        Base(std::move(other))   // here I want to call Base(Base &&tmp)
    {
        std::cout << "copy derived constructor called.\n";
    }

    Derived(Derived &&tmp)
    :
        Base(std::move(tmp))     // correctly calls Base(Base &&tmp)!
    {
        std::cout << "move derived constructor called.\n";
    }
};

所以在我的主函數中,我現在想調用復制構造函數,然后調用基類的移動構造函數。

int main()
{
    Derived der{};
    Derived der_copy{ der };
    Derived der_move{ std::move(der) };
}

我會得到的輸出是這樣的:

default base constructor called.
default derived constructor called.
copy base constructor called.         <-- why not move?
copy derived constructor called.
move base constructor called.
move derived constructor called.

我期待以下內容:

default base constructor called.
default derived constructor called.
move base constructor called.
copy derived constructor called.
move base constructor called.
move derived constructor called.

因此,當我在派生的移動構造函數中使用std::move(tmp)時(因此在Base &&tmp )調用了基礎移動構造函數,但是當我在派生的復制構造函數中使用std::move(other)時(在Base const &other ) 調用基本復制構造函數?

Tbh,這似乎很奇怪,恐怕我只是在代碼中犯了一個錯誤,我多次檢查了所有內容,但似乎無法在上述情況下調用移動基礎構造函數...

謝謝你的幫助!

在復制構造函數中

Derived(const Derived& other)

std::move(other)將導致類型為const Derived&&的 xvalue 表達式。

這是一個合法但有點奇怪的類型: std::move(other)是一個臨時對象,但你不能從中移動,因為它是常量。 此類引用的用例數量有限 有關一個特定示例,請參閱std::as_conststd::ref的聲明。

const Derived&&不能綁定到Base&& ,這就是為什么在重載解析期間

Base(const Base&)
Base(Base&&)

前者由編譯器選擇。

冒着出現未定義行為的風險,您可以拋棄常量並編寫

Derived(const Derived& other) : Base(std::move(const_cast<Derived&>(other))) {}

調用Base的移動構造函數。 但是不要在真正的代碼中這樣做。

你需要像這樣改變你的基類:

Base(const Base &&tmp) { std::cout << "move base constructor called.\n"; }

暫無
暫無

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

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