简体   繁体   中英

Transferring std::unique_ptr between Widgets

I have a Widget class, which is supposed to have unique ownership of another Widget. I want to implement a function which passes this Widget to another Widget. I learnt that the best way to implement the concept of single ownership is std::unique_ptr , however I can't get it to run

This is the code:

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;
};

It compiles without a problem, but when I try to run this:

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();
}

I get a Segmentation Fault. What is the problem?

And additionally, How would I have to write an implementation of the successor() function, if I wanted to pass Widget c . I could only get it running for rvalues.

Here

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

You're creating a unique_ptr to an object that would be destroyed once the scope exits.

Also, here

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

You're taking the address of an existing pointer in a unique_ptr , and assigning it to yet another unique_ptr . It's basically wrong/double deallocations all over the place here.

I'm highly unaware of what you're trying to do here. At any rate, if I can just limit myself to the number of changes relevant to memory management here in order to have this code make sense:

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM