I've been on Unity for quite a while and came back to do some C++ using Visual Studio 2015. I came across this class definition
class A
{
public:
A();
virtual ~A();
A(const A&) = delete;
A& operator=(const A&) = delete;
private:
…
}
This class is dynamically allocated like the following:
ObjPtr obj = ObjPtr(new A());
where ObjPtr
is a type defined and looks like:
typedef std::unique_ptr<A> objPtr;
and adding these created objects using to a std::vector<ObjPtr>
using std::move
. At one point, I need to loop through the list of objects, and if I find something that satisfies my criteria, keep a copy of it.
ObjPtr keep;
for(auto& object : GetObjectList() )
{
if(/*check if its the object I want*/)
{
keep = object;
}
}
Where GetObjectList returns a const std::vector<ObjPtr>&
.
But I'm getting an “attempting to reference a deleted function”. I did some googling and tried to remove the = delete
part and even commented the 2 lines out. I even tried to do
ObjPtr keep = std::move(object);
But I'm still getting the deleted function error. Can anyone see what I'm doing wrong or point me to some resources that can help?
A std::unique_ptr
cannot be copied. Even if the managed object could (but yours can't).
You have a couple of alternatives here (all with different effects):
Change the type of keep
to a non-owning raw pointer (aka A *
) and use keep = object.get();
. This is safe if and only if you know you won't use keep
longer than ObjectList
(or, more precisely, the object you take the address of) exists.
Move the std::unique_ptr
out of the container, that is, use keep = std::move(object);
. Of course, now you have a gap in ObjectList
. (I realize you have edited your question to say that ObjectList
is const
which means that you cannot modify and hence not move objects out of it.)
Change the type of ObjPtr
to std::shared_ptr<A>
if you want shared ownership semantics.
If you absolutely want a copy of the object, you could add a virtual
member function to A
that clones the object polymorphically.
class A
{
public:
virtual std::unique_ptr<A> clone() = 0;
…
};
You then implement that function in every leaf class
derived from A
. In your loop, you then use keep = object->clone();
. For this, you probably want to make the copy constructor protected
but don't delete
it.
Don't use keep = std::make_unique<A>(*object);
because it would not respect the actual (dynamic) type of the object and always slice to an A
. (Since your A
is not copyable, it wouldn't work anyway.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With