Reputation: 315
This is the code I cannot change and have to adapt to:
struct SomeInterface
{
...
};
struct SomeClass
{
SomeClass(SomeInterface& iface) : iface(iface) {}
SomeInterface& iface;
...
};
I have to write a function where I will get SomeInterface
from other function and return pointer to SomeClass
which takes a reference to SomeInterface
. The problem was, unique_ptr to SomeInterface
will be created on that function stack so reference is gonna be invalid after returning from it. I wrote a simple wrapper class which inherits from SomeClass
and extends it to hold a unique_ptr to SomeInterface
.
std::unique_ptr<SomeClass> getSomeClass()
{
struct SomeClassWrapper : public SomeClass
{
SomeClassWrapper(std::unique_ptr<SomeInterface> iface)
: SomeClass(*iface),
iface(std::move(iface)) {}
std::unique_ptr<SomeInterface> iface;
};
std::unique_ptr<SomeInterface> iface = getIfaceFromSomewhere();
return std::unique_ptr<SomeClass>(std::make_unique<SomeClassWrapper>(std::move(iface))
}
This solves SomeInterface's
lifetime problem... almost. Unfortunately during destruction of SomeClassWrapper
the member variable iface
is destroyed first, so for a brief moment base class SomeClass
holds a dangling reference.
How to achieve my desired result without this problem?
Cheers
Upvotes: 0
Views: 45
Reputation: 22152
Move the unique_ptr
into a base class that is constructed first and destructed last:
struct SomeClassWrapperPtrMember {
std::unique_ptr<SomeInterface> iface;
};
struct SomeClassWrapper : public SomeClassWrapperPtrMember, SomeClass
{
SomeClassWrapper(std::unique_ptr<SomeInterface> iface)
: SomeClassWrapperPtrMember{std::move(iface)},
SomeClass(*(this->iface)) {}
};
Upvotes: 1