2013-07-10 133 views
0

考慮下面的代碼:快速移動的構造函數/賦值運算符使用

#include <iostream> 

#define P_(x) std::cout << x << std::endl 

class B { 
public: 
    B() { P_("B::B()"); } 
    B(const B&) { P_("B::B(const B&)"); } 
    B(B&&) { P_("B::B(B&&)"); } 
    ~B() { P_("B::~B()"); } 

    B& operator=(const B&) { P_("B::op=(const B&)"); return *this; } 
    B& operator=(B&& b) { P_("B::op=(B&&)"); return *this; } 
}; 

class Foo { 
public: 
    void setB(const B& b) { mB = b; } 
private: 
    B mB; 
}; 

B genB() { 
    return B(); 
} 

int main() { 
    Foo f; 
    f.setB(genB()); 
} 

假設B是一種類型,它是難以複製的構建。我想生成一些B(使用函數genB)並將其存儲在Foo中。由於genB會返回臨時結果,因此我期望使用移動構造函數。

然而,當我運行代碼,我得到這樣的輸出:

B::B() 
B::B() 
B::op=(const B&) 
B::~B() 
B::~B() 

這清楚地表明,獲得創建和銷燬兩個B的,但第二個是一個副本,而不是第一個舉動。

什麼是儘可能使用移動構造函數的最佳方式?

  • 我需要在某處調用std :: move()嗎?
  • 我是否需要爲B&B&&單獨過載?
  • 還有什麼其他的完全是我失蹤?
+0

(實際上,第一個'B'被分配成爲第二個副本。) – aschepler

回答

3

你可以重載setB功能:

class Foo { 
public: 
    void setB(const B& b) { mB = b; } 
    void setB(B&& b) { mB = std::move(b); } 
private: 
    B mB; 
}; 

或者,您可以使用 「按值傳遞」 的方式:

class Foo { 
public: 
    void setB(B b) { mB = std::move(b); } 
private: 
    B mB; 
}; 

這裏,b將舉動構建在參數可能或複製構造否則。

0

第一B實例創建Foo實例時創建的一個:

Foo f; 

這是因爲你的Foo類有一個B成員稱爲mB

第二個B實例是由genB()調用創建的實例。

mB = b; 

無處是否有使用複製或移動構造一個機會:因爲分配您在Foo::setB功能進行

賦值操作符被調用。

相關問題