-1

I need to copy a std::unique_ptr<Interface> of some interface Interface.

This post sums it nice up, but it doesn't work in my case, because Interface doesn't have an available constructor.

Example:

//Pointer to copy
std::unique_ptr<Interface> ptr = std::make_unique<Interface>();

//error: incomplete type is not allowed
std::unique_ptr<Interface> copy{ new Interface(*ptr.get().data) };

Is there a way to deep copy ptr to copy?

Community
  • 1
  • 1
Rakete1111
  • 47,013
  • 16
  • 123
  • 162

2 Answers2

3

This is a problem with your Interface class, not unique_ptr. Your Interface class cannot be constructed based on dereferencing the return value of Interface::data.

Presumably, Interface is copy-constructible and non-polymorphic. If it is, you would simply copy construct it: make_unique<Interface>(*ptr). And if it's not copy-constructible, then you can't copy Interface at all. If it is a polymorphic type, then you have no ability to copy it correctly, unless the type is expressly coded to permit such things.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • **−1** "If [the interface is copy constructible], you would simply copy construct it: make_unique(\*ptr)" tells the OP to use a technical loophole that he fails to understand is that, to *slice* the object he wants to copy. Very ungood advice. – Cheers and hth. - Alf May 21 '16 at 20:27
  • @Cheersandhth.-Alf: Added note about polymorphic types. – Nicol Bolas May 21 '16 at 20:36
3

Add

virtual std::unique_ptr<Interface> clone() const = 0;

To Interface. Implement it in the final class of interface's implementation with:

virtual std::unique_ptr<Interface> clone() const override final {
  return std::make_unique<Implementation>(*this);
}
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
  • I guess that would be possible, but `Interface` is from a library, and I can't modify it. Thanks though – Rakete1111 May 21 '16 at 20:23
  • Also, there's really no reason to make that a member function. It's just as easy to write a `unique_ptr_clone` function that will clone any `T` that is copy-constructible. – Nicol Bolas May 21 '16 at 20:25
  • 2
    @NicolBolas: No, the function needs to be virtual. A separate function would just slice the object. – Cheers and hth. - Alf May 21 '16 at 20:29
  • @Cheersandhth.-Alf: Or you SFINAE protect it against polymorphic types, just as you would against non-copy-constructible types. – Nicol Bolas May 21 '16 at 20:35
  • @NicolBolas: No, this is an ["interface" class](https://en.wikipedia.org/wiki/Interface_%28computing%29#Software_interfaces_in_object-oriented_languages). I linked that to Wikipedia's article about it. – Cheers and hth. - Alf May 21 '16 at 20:38
  • @rakete without the unique_ptr, how would you copy a pointer to interface? What does it mean to cooy it? How did you create it? Who wrapped it in a unique_ptr? These can lead to a different solution. – Yakk - Adam Nevraumont May 21 '16 at 20:38
  • @Cheersandhth.-Alf: No, it's a class *named* `Interface`. – Nicol Bolas May 21 '16 at 20:38
  • Because it's a pointer I can copy it, the library exposes raw pointers, and I'm wrapping them in smart pointers. (Maybe I missinterpreted the name "Interface", isn't that what's it called, a non-default constructible class, that can only be constructed through factory instances?) – Rakete1111 May 21 '16 at 20:42
  • @rake copying the pointer to `Interface` does not copy the `Interface`. You get two pointers to the *same* instance of `Interface`. A `unique_ptr` considers itself *owning* that object, with unique power and resonsibility to delete the object. – Yakk - Adam Nevraumont May 21 '16 at 20:45
  • Yes I know that :) – Rakete1111 May 21 '16 at 20:57
  • @rake then what are you asking? – Yakk - Adam Nevraumont May 21 '16 at 21:04
  • I couldn't figure out how to copy the type (even though it was straightforward) in a unique ptr to another one – Rakete1111 May 21 '16 at 21:05
  • @rake but a unique_ptr claims unique and sole ownership. Copy that makes little sense; how can two smart pointers both have unique and sole ownership of the same object? Are you aware of `std::move`? – Yakk - Adam Nevraumont May 21 '16 at 21:14
  • Yes, but then I would have to move every time I use the class, and that would be a lot – Rakete1111 May 21 '16 at 21:15
  • @rake everytime you transfer ownership from one pointer to another from a non-expiring value, yes? – Yakk - Adam Nevraumont May 21 '16 at 21:16
  • @rake You claim "every time you use the class", but you only have to move when you want to transfer ownership in a situation where a move does not automatically happen. You claim to understand move, unique ptr ownership rules, and pointer ownership rules, and I have no idea why you are still confused. Probably because you do not uderstand these things... – Yakk - Adam Nevraumont May 21 '16 at 22:02
  • I didn't mean that literally, but the thing is, I would like to copy the class fully, without moving ownership of the pointers involved. That's why I asked, because I couldn't figure out how to copy that class that is in a unique pointer. But you're right, I don't understand move semantics and ownership a lot – Rakete1111 May 21 '16 at 22:09
  • @NicolBolas: The OP says it's "some interface Interface". Your idea that it's a class that just by happenchance is named `Interface`, is stupid as a way to rescue your position. At this point I do not believe it's still a misunderstanding on your part. – Cheers and hth. - Alf May 21 '16 at 23:06