I have a function foo
. During the execution of foo
, I want to be certain that an object of type Bar
exists. Let’s call whatever object that happens to be “bar
.”
I cannot copy or move bar
, and bar
can have any storage duration. The one thing I do know about bar
is that it is an empty object.
foo
doesn't need to do anything with bar
or know anything about it.
First thought is, pass a
Bar&
intofoo
to tell the calling environment, “hey, you need to make surebar
exists while I’m running!” But the calling environment could pass a dangling reference intofoo
, in which casebar
would be destroyed beforefoo
runs.Second thought is, pass a
shared_ptr
tobar
in. But (correct me if I’m wrong) this would requirebar
to have dynamic storage duration.Third thought is, write a helper type that is copyable and movable that guarantees the existence of
bar
. But this feels like reinventing theshared_ptr
wheel.
What are my options for ensuring bar
exists during foo
, and what are their strengths and limitations?
CodePudding user response:
the calling environment could pass a dangling reference into foo
It really couldn't. Dangling references are not legal, so the only way for this to happen is by the caller violating the language rules. I don't find this a compelling concern.
pass a shared_ptr to bar in. But this would require bar to have dynamic storage duration.
Not quite. A shared_ptr can be constructed with a custom deleter, so if the caller wants to pass in a "stack allocated" Bar
, they can construct a shared_ptr with a deleter which does not delete anything.
bar is that it is an empty object
Then what's the point of the entire exercise? Is it because the Bar
constructor and/or destructor have side effects which must occur before/after foo
runs? If that's the case, maybe foo
should just do those things itself, or a foo_wrapper
function can be created to hide these details.