初始化unique_ptr会导致AN&quot“错误:使用已删除函数”即使它s&quot s&quot std :: move”
我正在编写代码,该代码通过看起来不好的几层传递std :: unique_ptr
,但是我别无选择,但现在一直通过它。
问题在于,当我尝试将std :: unique_ptr
传递给提供者
类的构造函数时,我会遇到错误。在Child :: function1()
的点,child
已使用inpland> impl&
和std的参数进行了初始化/构造:: Unique_ptr< retriever>
来自其他地方。
有人可以告诉我为什么我会遇到这个错误,以及如何获得此工作?我想知道这是否是因为继承发生了,但是除了搬家以获得这项工作之外,我还不知道该怎么办与相同的构造函数...大声笑)
// 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;
}
I am writing code that passes a std::unique_ptr
through a few layers that look bad, but I don't have a choice but pass it all along for now.
The problem is that I am getting an error when I try to pass the std::unique_ptr
to a constructor of the Provider
class. At the point where Child::function1()
is called, Child
has been initialized/constructed with parameters of Impl&
and std::unique_ptr<Retriever>
from somewhere else.
Could someone please tell me why I'm getting this error, and how to get this work? I wonder if it's because of the inheritance happening, but I can't figure it out what else to do besides moving to get this work... (apart from something like not to pass this ptr through all these classes that seem to look similar with the same constructors... lol)
// 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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在
Child :: function1()
中,您正在将d_retriever_up
by Value 传递给提供者
构造函数。这需要制作d_retriever_up
的副本,这是不可能的,因为它是unique_ptr
具有delete> delete
'd的复制构造函数,因此错误。您需要使用
std :: move()
将d_retriever_up
移动到提供者
中。您声称这样做,但您不是,至少不是在需要的任何地方。将呼叫者的unique_ptr
移动到提供商
constructor的retriever_up
参数是一个单独的操作,而不是将retriever_up
参数移动到<<代码>提供商'sd_retriever
类成员。但是,解决此问题后,您将遇到另一个问题。
child :: function1()
被标记为const
,它可以访问d_retriever_up
beconst> const
在该上下文中,因此,function1()
无法修改d_retriever_up
,包括移动(因为移动unique_ptr
将其固定指针设置为nullptr
)。因此,要使代码正常工作,您需要删除
const
并添加std :: move()
:也就是说,移动
d_retriever_up
在您的设计中值得怀疑。您可能需要考虑使用std :: shared_ptr
。In
Child::function1()
, you are passingd_retriever_up
by value to theProvider
constructor. That requires making a copy ofd_retriever_up
, which is impossible as it is aunique_ptr
that hasdelete
'd its copy constructor, hence the error.You need to use
std::move()
to moved_retriever_up
intoProvider
. You claim to be doing that, but you are not, at least not everywhere it is needed. Moving the caller'sunique_ptr
into theProvider
constructor'sretriever_up
parameter is a separate operation than moving theretriever_up
parameter into theProvider
'sd_retriever
class member.However, after you fix that, you will run into another problem.
Child::function1()
is marked asconst
, which makes access tod_retriever_up
beconst
in that context, sofunction1()
can't modifyd_retriever_up
, including moves (since moving aunique_ptr
sets its held pointer tonullptr
).So, to make the code work, you need to drop the
const
and addstd::move()
:That being said, moving
d_retriever_up
is questionable in your design. You might need to consider usingstd::shared_ptr
instead.