Say we have class Foo:
class Foo {
public:
...
};
Foo has an instance method which either transforms the Foo instance into another Foo instance, or returns the same Foo instance:
<some appropriate pointer type to Foo> Foo::tryToTransform() {
if (canBeTransformed()) {
<delete this Foo instance>;
return <new instance of Foo>;
}
else {
return <this instance of Foo>;
}
}
Client code:
<some appropriate pointer type to Foo> foo = ...;
...
foo = foo->tryToTransform();
This is easy to do with naked pointers:
Foo* Foo::tryToTransform() {
if (canBeTransformed()) {
delete this;
return new Foo(...);
}
else {
return this;
}
}
Foo* foo = ...;
...
foo = foo->tryToTransform();
But what if the client code uses a unique_ptr instead of a naked pointer? That is, ideally I would like the client code to look like this:
unique_ptr<Foo> foo = ...;
...
foo = foo->tryToTransform();
How should Foo::tryToTransform() be defined in order to enable such (or similar) client code?
Because your tryToTransform function is a member function, the caller retains ownership of the unique_ptr. It is therefore impossible (without dirty tricks) to delete a caller's unique_ptr from inside the member function.
Therefore, you need a static function that takes ownership of the unique_ptr:
class Foo {
static unique_ptr<Foo> tryToTransform(unique_ptr<Foo> ptr) {
if(...) {
return unique_ptr<Foo>(new Foo()); // old ptr is destroyed
} else {
return ptr;
}
};
Call as
unique_ptr<Foo> foo = ...;
...
foo = Foo::tryToTransform(move(foo));
This works by having tryToTransform take ownership of the unique_ptr. It is then able to destroy the pointer as it wishes.
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