C++ 这是唯一的ptr的正确用法吗?

C++ 这是唯一的ptr的正确用法吗?,c++,return,smart-pointers,unique-ptr,C++,Return,Smart Pointers,Unique Ptr,通过阅读这里的大多数问题(在查找唯一指针时会弹出)我发现,在我看来,它应该提供构建器模式所描述的行为 我希望Builder的任何实例(或其子类,因为它不实现任何修改正在构造的对象的过程)拥有正在构造的对象,直到Close返回指向调用方的唯一指针,此时调用方获得所有权 建筑商 template <class type> class Builder { public: ~Builder(); unique_ptr<type> Close(); protecte

通过阅读这里的大多数问题(在查找唯一指针时会弹出)我发现,在我看来,它应该提供构建器模式所描述的行为

我希望Builder的任何实例(或其子类,因为它不实现任何修改正在构造的对象的过程)拥有正在构造的对象,直到Close返回指向调用方的唯一指针,此时调用方获得所有权

建筑商

template <class type> class Builder
{
public:
    ~Builder();
    unique_ptr<type> Close();
protected:
    Builder();
    unique_ptr<type> _uptr;
};
模板类生成器
{
公众:
~Builder();
唯一的_ptr Close();
受保护的:
生成器();
独特的_ptr _uptr;
};
Builder.cpp

template<class type> Builder<type>::Builder()
{
    uptr = make_unique<type>();
}

template<class type> Builder<type>::~Builder()
{}

template<class type> unique_ptr<type> Builder<type>::Close()
{
    return uptr;
}
模板生成器::生成器()
{
uptr=使_唯一();
}
模板生成器::~Builder()
{}
模板唯一\u ptr生成器::关闭()
{
返回uptr;
}
我是否理解按值传递唯一指针的语义


(为了简洁/易读,省略了包含和名称空间)

std::unique\u ptr无法复制。相反,为了正确地转移底层指针的所有权,您必须向上移动指针

template<class type> unique_ptr<type> Builder<type>::Close()
{
    return std::move(uptr);
}
template unique\u ptr Builder::Close()
{
返回标准::移动(uptr);
}
我是否理解按值传递唯一指针的语义

您可以从一个唯一的\u ptr:
std::move(this->\u uptr)

小心移动,因为它们会使原始对象的内容无效

我已经完成了您的示例,以举例说明威胁:

#include <iostream>
#include <memory>

template<typename T> class Builder
{
public:
    virtual ~Builder() {}
    std::unique_ptr<T> Close();
protected:
    Builder() {}
    std::unique_ptr<T> _uptr;
};

class IntBuilder: public Builder<int>
{
public:
    IntBuilder() : Builder<int>() {
        this->_uptr = std::unique_ptr<int>(new int);
    }
    void setValue(int x) {
        *(this->_uptr) = x;
    }
    std::unique_ptr<int> Close() {
        return std::move(this->_uptr);
    }
};

int main() {
    IntBuilder b;
    b.setValue(3);
    auto i = b.Close();
    std::cout << *i << std::endl; // OK
    auto i2 = b.Close();
    std::cout << *i2 << std::endl; // Segmentation fault
}

谢谢这是有道理的。我隐约感觉到我没有恰当地实现转移。我清楚地意识到我最初定义的严格性。部分原因是这将最终成为一个更大的课程交付的一部分,其评分标准完全集中在我们对C++设计模式的理解和使用上。我也在团队中工作,我们都是新的语言,因此,为更原始的用户定义类型提供严格的使用模式似乎可以消除同龄人的歧义。不过,我看到了这样做背后的动机。读这篇文章:我仍然有点不清楚当Close返回时到底发生了什么。如果生成器实例是MyClassBuilder,返回一个包含大量成员、一些值、一些指针的对象实例,那么所有权会发生什么变化?是否通过移动内部构件来避免复制(&D)?或者它是复制的,因为T的实例不是临时的?我很犹豫是否要将我的实现修改为我不完全理解的实现。对于任何阅读本文的人,下面的文章为我澄清了T&&的语义。
template<typename T> class Builder
{
public:
    virtual ~Builder() {}
    T&& Close();
protected:
    Builder() {}
};