Sounds like that instead of moving the unique pointer, you might actually want to just get() the raw pointer and pass that somewhere else? Raw pointers are still just fine, as long as you use them for non-owning purposes.
EA::OwningPointer<Button> widget;
//creates a new Button:
widget.create();
//creates a new TextButton
widget.create<TextButton>();
void funcThatTakesRawPointer(Button* button);
//no .get() calls are needed:
funcThatTakesRawPointer(widget);
It implements the ‘clone()’ pattern so if your derived types have that, you can copy a polymorphic container without lots of boilerplate.
void setSomething(unique_ptr<Component> b)
{
b->doSomething();
container.push_back(std::move(b));
/// many lines of code
if (someRareCondition())
b->doSomethingElse();
}
You mean you never make an object and then give it to another class?
It’s sort of the thing that say JUCE Viewport does, or a million other bits of the library. We do it all the time, especially in UI code where we want some reusable code to be agnostic about whatever component we pass to it is…
Yes, I think passing ownership is usually something you want to avoid in modern C++. Passing a reference/raw non owning pointer should be just fine.
ViewPort, IMO, should only take the Component it manages by reference/pointer and never delete it later, and the fact it does take ownership is for legacy reasons.
Alternatively if you want to create the component in place to be owned by the class, you can create it directly by doing something like:
And then never expose the creation structure or let the user do something risky like moving a unique_ptr and figuring out who owns it in two pieces of code.
Your example exactly highlights one of the benefits of unique_ptr. In many lines of code can you be sure b hasn’t be deleted from the container?
The semantics are correct here, if you’ve transferred ownership to something else, it’s that something else’s responsibly to give you access to it. Use container.back()?
This is what leads to bad practices like using shared_ptr all over the place IME.
Moving ownership is something you should try to limit as much as possible, but there are times when one object needs to hand off something it owned to another - that’s why we have move semantics after all?
Depends on your container whether this is free or not probably? And I think it makes my code look ugly
I mean really I think my issue is that just don’t like having a new category of error to worry about. And I’d trained myself to avoid all the pitfalls of the previous way without really having to think. And thinking is a lot of effort.
Tangentially - Ever wondered why thinking is a lot of effort? It’s a bit weird, it’s not like it uses loads more calories, so why does thinking hard feel like a strain… curious bit of evolution that!
This is really bad advise. Not only is there an additional cost involved with shared_ptr, it completely tramples over all the ownership semantics that unique_ptr tries to enforce for you, for good reason. Very easy to get cyclic references if you’re always using shared_ptr…