简体   繁体   中英

design headache with unique_ptr

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM