提问人:user2465084 提问时间:6/25/2022 最后编辑:user2465084 更新时间:6/25/2022 访问量:571
初始化unique_ptr会导致“错误:使用已删除的函数”,即使它是“std::move”ed
Initializing unique_ptr causes an "error: use of deleted function" even though it's "std::move"ed
问:
我正在编写代码,这些代码通过几个看起来很糟糕的层,但我别无选择,只能暂时将其全部传递。std::unique_ptr
问题是当我尝试将 传递给类的构造函数时,我遇到了错误。在调用点,已使用其他地方的参数初始化/构造。std::unique_ptr
Provider
Child::function1()
Child
Impl&
std::unique_ptr<Retriever>
有人可以告诉我为什么我会遇到这个错误,以及如何获得这个工作吗?我想知道是不是因为继承的发生,但我不知道除了搬家得到这份工作之外还能做什么......(除了不要通过所有这些看起来与相同构造函数相似的类来传递此 PTR 之类的东西......哈哈)
// child.cpp
Child::Child(Impl& child_impl, std::unique_ptr<Retriever> child_retriever_up)
: Parent(child_impl, std::move(child_retriever_up))
{}
T::Y Child::function1() const
{
**Provider provider(d_impl, d_retriever_up);**
// these d_impl and d_retriever are in Parent class.
...
return Y;
}
// child.h
class Child : public Parent {
public:
// creators
explicit Child(Impl& child_impl, std::unique_ptr<Retriever> child_retriever_up);
~Child() override = default;
// accessors
T::Y Child::function1() const;
private:
Child(const Child&) = delete;
Child& operator=(const Child&) = delete;
// parent.cpp
Parent::Parent(Impl& impl, std::unique_ptr<Retriever> retriever_up)
: d_impl(impl), d_retriever_up(std::move(retriever_up))
{}
// parent.h
class Parent {
public:
// creators
explicit Parent(Impl& impl, std::unique_ptr<Retriever> retriever_up);
virtual ~Parent() = default;
// copy constructor
Parent(const Parent& parent)
: d_context(parent.d_impl)
, d_retriever_up(std::move(*parent.d_retriever_up))
{
}
// data
Impl& d_impl;
std::unique_ptr<Retriever> d_retriever_up;
private:
//Parent(const Parent&) = delete;
Parent& operator=(const Parent&) = delete;
// provider.cpp
Provider::Provider(Impl& impl, std::unique_ptr<Retriever> retriever_up)
: d_impl(impl)
, d_retriever(std::move(retriever_up))
{}
// provider.h
class Provider {
public:
Provider(Impl& context, std::unique_ptr<Retriever> retriever_up);
//copy contstructor
Provider(const Provider& provider)
: d_impl(provider.d_impl)
, d_retriever(std::move(*provider.d_retriever))
{
}
private:
Impl& d_impl;
std::unique_ptr<Retriever> d_retriever;
}
答:
在 中,您将按值传递给构造函数。这需要制作 的副本,这是不可能的,因为它具有其复制构造函数,因此会出现错误。Child::function1()
d_retriever_up
Provider
d_retriever_up
unique_ptr
delete
您需要使用 to 移动到 .你声称正在这样做,但你没有,至少不是在所有需要它的地方。将调用方的参数移动到构造函数的参数中与将参数移动到 的类成员中是不同的操作。std::move()
d_retriever_up
Provider
unique_ptr
Provider
retriever_up
retriever_up
Provider
d_retriever
但是,在解决此问题之后,您将遇到另一个问题。 标记为,这使得访问位于该上下文中,因此无法修改 ,包括移动(因为移动 a 会将其持有指针设置为 )。Child::function1()
const
d_retriever_up
const
function1()
d_retriever_up
unique_ptr
nullptr
因此,要使代码正常工作,您需要删除 并添加:const
std::move()
T::Y Child::function1()
{
Provider provider(d_impl, std::move(d_retriever_up));
...
return Y;
}
话虽如此,移动在你的设计中是有问题的。您可能需要考虑改用。d_retriever_up
std::shared_ptr
评论
d_retriever
unique_ptr