vendredi 29 janvier 2016

problems with shared_from_this in constructor

I understand why shared_from_this doesn't work in the constructor. I've found a number of posts on here clearly explaining why. I've also seen a workaround for it. My problem is related to this but I'm looking for an elegant workaround.

I quite like this kind of design

class Foo : public enable_shared_from_this<Foo> {
public:
  typedef shared_ptr<Foo> Ptr;

  Ptr setA(int) {/* .... */ return this->shared_from_this(); } 
  Ptr setB(int) {/* .... */ return this->shared_from_this(); } 
  Ptr setC(int) {/* .... */ return this->shared_from_this(); } 
};

so I can daisy chain like this, which I find very readable

Foo::Ptr foo = make_shared<Foo>();
foo->setA(3)->setB(4)->setC(5);

However, my setX methods do more than just assign the value to a property, they might do slightly more complex things (like set other properties etc). So I'd like to use them in my constructor. i.e.

Foo::Foo(int a, int b, int c) {
    setA(a);
    setB(b);
    setC(c);
}

Of course this crashes. However in my case I don't actually need a shared this pointer in my constructor. It's just a side-effect of my wanting to daisy chain later.

A dirty fix could be I just make a bunch of private setX_ methods which do the actual assignment and other tasks, but don't return anything. The constructor calls those. Then I have public setX methods simply call the private ones and then return the this->shared_from_this(). That's safe, but a bit of a PITA. Is it possible to check if a shared pointer to this already exists without crashing? i.e.

class Foo : public enable_shared_from_this<Foo> {
public:
  typedef shared_ptr<Foo> Ptr;

      Ptr setA(int) { /*.....*/ return getThis(); }

protected:
    Ptr getThis() {
        return safe_to_get_this ? this->shared_from_this : Ptr();
    }

};

Aucun commentaire:

Enregistrer un commentaire