shared_ptr and the this-pointer

Pat*_*ick 8 c++ this shared-ptr this-pointer

OK, I started using shared-pointers and pass shared-pointers as much as possible. No conversion to raw pointers anymore. This works good, except in this specific case:

Suppose we have a class that also is an observer on another class, like this:

class MyClass : public IObserver
   {
   public:
      MyClass (std::shared_ptr<SomeOtherClass> otherClass);
      void DoSomethingImportant();
   private:
      std::shared_ptr<SomeOtherClass> m_otherClass;
   };
Run Code Online (Sandbox Code Playgroud)

This class is used like this in my application:

std::shared_ptr<MyClass> myInstance(new MyClass(otherInstance));
...
myInstance->DoSomethingImportant();
Run Code Online (Sandbox Code Playgroud)

MyClass gets a shared-pointer to another class and stores this in its m_otherClass data member. In the DoSomethingImportant method, the MyClass instance does lots of important things, including registering itself as an observer on m_otherClass, like this:

m_otherClass->registerObserver(this);

The problem is that the registerObserver method is defined like this:

void registerObserver (std::shared_ptr observer);

It expects a shared pointer, but 'this' is a raw pointer, not a shared one.

I see three ways of solving this:

  • Find a trick to convert a normal pointer to a shared pointer (see question convert pointer to shared_ptr), but the answers to that question only suggest to copy the shared-pointers, not on how to actually convert the pointer to a shared pointer.
  • Pass the shared-pointer to ourself to the method, like this: "myInstance->DoSomethingImportant(myInstance);" which seems a bit stupid.
  • Put the observer part into a separate class. This looks like some overkill, and might make the class harder to understand.

This problem makes it obvious that shared-pointers are just an add-on to C++ (I don't think you have the same problem in other languages/environments like C# (or .Net in general) and Java).

Any other suggestions or tricks on how to handle this situation?

Dav*_*eas 8

你需要的可能是enable_shared_from_thisshared_from_this设施.文档在这里

请注意,shared_from_this在构造函数完全完成且对象已被另一个对象拥有之前,您无法使用shared_ptr.

struct test : boost::enabled_shared_from_this<test>
{
    test() {
       // shared_from_this(this); // error, still not owned by another shared_ptr
    }
    boost::shared_ptr<test> shared() {
       return shared_from_this(this);
    }
};
int main() {
   test * t = new test;
   // boost::shared_ptr<test> p = t->shared(); // error, not yet owned by other shared_ptr
   boost::shared_ptr<test> owner( t ); 
   boost::shared_ptr<test> p = t->shared();     // [*] ok, "owner" owns the object
}
Run Code Online (Sandbox Code Playgroud)

[*]这部分示例很愚蠢,您可以将所有者复制到p中,而不是调用该方法.它只是提示注意何时可以shared_from_thistest方法内部调用.