2016-02-24 19 views
0

我有一個Widget類,它應該擁有另一個Widget的唯一所有權。 我想實現一個函數,該函數將此Widget傳遞給另一個Widget。我瞭解到,實行單一所有權的概念最好的辦法是std::unique_ptr,但是我不能讓它跑在Widgets之間傳遞std :: unique_ptr

這是代碼:

class Widget 
{ 
public: 
    Widget(void) { } 
    virtual ~Widget(void) { /* */ } 
    void successor(Widget&& successor) 
    { 
     this->_successor = std::unique_ptr<Widget>(&successor); 
    } 
    void refer_value(int a) 
    { 
     _successor->value = a; 
    } 
    auto refer_value(void) const -> int 
    { 
     return _successor->value; 
    } 
    auto get(void) -> Widget& 
    { 
     return *_successor; 
    } 

    int value; 
private: 
    std::unique_ptr<Widget> _successor; 
}; 

它編譯沒有問題,但是當我嘗試運行此:

int main(void) 
{ 
    Widget a{}; 
    Widget b{}; 
    Widget c{}; 

    a.successor(Widget{}); 
    a.refer_value(5); 

    b.successor(std::move(a.get())); 
    std::cout << b.refer_value(); 
} 

我得到一個分段錯誤。問題是什麼?

此外,如果我想通過Widget c,如何編寫繼承者()函數的實現。我只能運行rvalues。

回答

3

這裏

this->_successor = std::unique_ptr<Widget>(&successor); 

你正在創建一個unique_ptr到將一次範圍退出被破壞的對象。

而且,這裏

b.successor(std::move(a.get())); 

你正在做的unique_ptr現有的指針的地址,並將其分配給又一unique_ptr。這裏基本上是錯誤/雙重釋放。

我是高度不知道你要在這裏做什麼。無論如何,如果我可以限制自己纔能有這樣的代碼相關的內存管理這裏變化的數字意義:

class Widget 
{ 
public: 
    Widget(void) { } 

    virtual ~Widget(void) { /* */ } 

    void successor(std::shared_ptr<Widget> successor) 
    { 
     this->_successor = std::move(successor); 
    } 

    void refer_value(int a) 
    { 
     _successor->value = a; 
    } 

    auto refer_value(void) const -> int 
    { 
     return _successor->value; 
    } 

    std::shared_ptr<Widget> get() 
    { 
     return _successor; 
    } 

    int value; 

private: 
    std::shared_ptr<Widget> _successor; 
}; 

int main(void) 
{ 
    Widget a{}; 
    Widget b{}; 
    Widget c{}; 

    a.successor(std::make_shared<Widget>()); 
    a.refer_value(5); 

    b.successor(a.get()); 
    std::cout << b.refer_value(); 
} 
+0

我想保證,沒有兩個小工具指向同一個部件。然而當我在你的代碼中調用'std :: cout << a.refer_value();'時,我也得到了5. – hgiesel

+0

@henrikgiesel你可以使':: get()'返回'std :: shared_ptr &'然後將它移動到b.successor()中。然而,'a.refer_value()'會解引用一個空指針,所以你必須小心這個。 –

+0

我想我可以通過調用指針上的'operator bool'來繞過這個問題。不過,我仍然想要一個解決方案'std :: unique_ptr' – hgiesel