2011-02-02 77 views
6

好的,我开始使用共享指针并尽可能传递共享指针。不再转换为原始指针。这工作不错,但在这种特殊情况下:shared_ptr和这个指针

假设我们有一个类,也就是对另一个阶级的观察者,像这样:

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

该类用于像这样在我的应用程序:

std::shared_ptr<MyClass> myInstance(new MyClass(otherInstance)); 
... 
myInstance->DoSomethingImportant(); 

MyClass获取到另一个类的共享指针并将其存储在其m_otherClass数据成员中。 在DoSomethingImportant方法中,MyClass实例做了很多重要的事情,包括在m_otherClass上注册自己作为观察者,如下所示:

m_otherClass-> registerObserver(this);

的问题是,该registerObserver方法这样定义:

空隙registerObserver(STD :: shared_ptr的观察者);

它期望一个共享指针,但'this'是一个原始指针,而不是共享指针。

我看到解决这一三种方式:

  • 找到一招正常指针转换为共享指针(见问题convert pointer to shared_ptr),但回答这个问题,只建议复制共享指针,而不是如何将指针实际转换为共享指针。
  • 将共享指针传递给方法,如下所示:“myInstance-> DoSomethingImportant(myInstance);”这似乎有点愚蠢。
  • 将观察者部分放入单独的类中。这看起来有点矫枉过正,可能会让班级更难理解。

这个问题很明显,共享指针只是C++的一个附加组件(我认为在其他语言/环境(如C#(或.Net)和Java)中不存在相同的问题)。

有关如何处理这种情况的其他建议或窍门?

+2

你不能使用`enable_shared_from_this`吗? (请参阅[从此获取提升shared_ptr])(http://stackoverflow.com/questions/142391/getting-a-boostshared-ptr-for-this)) – 2011-02-02 08:49:17

+3

谁在调低此问题和所有答案?这真的是一个如此愚蠢的问题吗? – Patrick 2011-02-02 09:05:24

+0

我有时会怀疑......如果有些人不只是简单地试图获得徽章http://stackoverflow.com/badges/7/critic?userid=147192 – 2011-02-02 09:09:46

回答

8

你需要的可能是enable_shared_from_thisshared_from_this设施。该文档是here

请注意,您不能使用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 
} 

[*]这部分示例很愚蠢,您可以将所有者复制到p中,而不是调用方法。它只是在test方法内部提出要注意何时可以或不需要调用shared_from_this

0

如何使构造私人和具有静态构造方法是这样的:

class MyClass : public IObserver 
    { 
    public: 
     static std::shared_ptr<MyClass> createObserver(std::shared_ptr<SomeOtherClass> otherClass); 
     void DoSomethingImportant(); 
    private: 
     MyClass (std::shared_ptr<SomeOtherClass> otherClass); 
     std::shared_ptr<SomeOtherClass> m_otherClass; 
    }; 

然后,你可以在静态方法实例干净的观察者,而不必担心这个指针都没有。

0


您可以将注册步骤移至单独的方法吗? :

shared_ptr<SomeOtherClass> other(new SomeOtherClass()); 
shared_ptr<MyClass> my(new MyClass()); 
// register myself to the observer 
other->registerObserver(my); 
my->DoSomethingImportant(); 

观察者模式的一个好的设计可以用的boost ::信号来实现和boost ::绑定 库。我鼓励你看看。

最好的问候,
马辛

3

对于观察者模式,被观察对象没有考虑观察者的所有权,为什么不直接使用原始指针?观察员的生命周期应该由观察员自己来控制。

通过使用enable_shared_from_this,您可以为观察者及其观察对象引入循环依赖。这意味着如果不明确删除,资源将永远不会被释放。