C++ 在小部件之间传输std::unique_ptr

C++ 在小部件之间传输std::unique_ptr,c++,pointers,smart-pointers,unique-ptr,C++,Pointers,Smart Pointers,Unique Ptr,我有一个Widget类,它应该拥有另一个Widget的唯一所有权。 我想实现一个将这个小部件传递给另一个小部件的函数。我了解到实现单一所有权概念的最佳方法是std::unique\u ptr,但我无法让它运行 代码如下: class Widget { public: Widget(void) { } virtual ~Widget(void) { /* */ } void successor(Widget&& successor) {

我有一个Widget类,它应该拥有另一个Widget的唯一所有权。 我想实现一个将这个小部件传递给另一个小部件的函数。我了解到实现单一所有权概念的最佳方法是
std::unique\u 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;
};
类小部件
{
公众:
控件(无效){}
虚拟~Widget(void){/**/}
无效后续程序(小部件和后续程序(&S)
{
此->_succession=std::unique_ptr(&succession);
}
无效参考值(int a)
{
_后继->值=a;
}
自动参考值(无效)常量->整数
{
返回_继任者->值;
}
自动获取(void)->Widget&
{
返回*\u继任者;
}
int值;
私人:
std::唯一的ptr继承者;
};
它编译时没有问题,但当我尝试运行此命令时:

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();
}
int main(无效)
{
小部件a{};
小部件b{};
控件c{};
a、 后继程序(Widget{});
a、 参考值(5);
b、 继承者(std::move(a.get());
std::cout这里

您在
唯一\u ptr
中获取现有指针的地址,并将其分配给另一个
唯一\u 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();
}
类小部件
{
公众:
控件(无效){}
虚拟~Widget(void){/**/}
无效后继程序(标准::共享后继程序)
{
this->_succession=std::move(succession);
}
无效参考值(int a)
{
_后继->值=a;
}
自动参考值(无效)常量->整数
{
返回_继任者->值;
}
std::shared_ptr get()
{
返回继任者;
}
int值;
私人:
std::共享的ptr继承者;
};
内部主(空)
{
小部件a{};
小部件b{};
控件c{};
a、 继任者(std::make_shared());
a、 参考值(5);
b、 继承人(a.get());
std::cout这里

您在
唯一\u ptr
中获取现有指针的地址,并将其分配给另一个
唯一\u 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();
}
类小部件
{
公众:
控件(无效){}
虚拟~Widget(void){/**/}
无效后继程序(标准::共享后继程序)
{
this->_succession=std::move(succession);
}
无效参考值(int a)
{
_后继->值=a;
}
自动参考值(无效)常量->整数
{
返回_继任者->值;
}
std::shared_ptr get()
{
返回继任者;
}
int值;
私人:
std::共享的ptr继承者;
};
内部主(空)
{
小部件a{};
小部件b{};
控件c{};
a、 继任者(std::make_shared());
a、 参考值(5);
b、 继承人(a.get());

std::我可以保证,没有两个小部件指向同一个小部件。但是,当我调用
std::cout@henrikgiesel时,您可以使
::get()
返回
std::shared\u ptr&
然后
move()
将其放入
b.succession()
。但是,然后
a.参考值()
将取消对空指针的引用,因此您必须小心。我想我可以通过调用指针上的
运算符bool
来避免这种情况。但是,我仍然希望为
std::unique\u ptr
@henrikgiesel找到一个解决方案,然后使用
unique\u ptr
仅用于所有权和原始指针的引用。但是,请注意那么,当拥有的小部件超出范围时,除非你做些什么,否则原始指针仍然可以访问。在这里使用
shared\u ptr
似乎更好。@henrikgiesel>1
unique\u ptr
s指向同一指针-->我想保证,没有两个小部件指向同一个小部件。但是当我调用
std::cout@henrikgiesel您可以制作
::get()
返回
std::shared\u ptr&
,然后
move()
将其放入
b.succession()
。但是,然后
a.参考值()
将取消对空指针的引用,因此您必须小心。我想我可以通过调用指针上的
运算符bool
来避免这种情况。但是,我仍然希望为
std::unique\u ptr
@henrikgiesel找到一个解决方案,然后使用
unique\u ptr
仅用于所有权和原始指针的引用。但是,请注意那么,当拥有的小部件超出范围时,原始指针仍然可以访问,除非您对此做些什么。在这里使用
shared\u ptr
似乎更好。@henrikgiesel>1
unique\u ptr
s指向同一指针-->定时炸弹
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();
}