【问题标题】:RAII objects in a singleton container?单例容器中的 RAII 对象?
【发布时间】:2014-11-23 02:16:24
【问题描述】:

所以,我想知道如何使用某种跟踪机制在 C++ 中创建某种代码审核

考虑以下类,其中两个独立的镜像 A 和 B 向侦听器提供消息。

class MirrorA
{
  void one(int a) {  m_mirrrorListener.three(a); }
};

class MirrorB
{
  void two(int b) {  m_mirrrorListener.three(b); }
};

class MirrorListener
{
  void three(int c) { std::cout << c << std::endl; }
};

现在,假设出于某种原因,三个需要知道它是由 one() 还是由 two() 触发的。

我们可以像这样传递一个值:

enum mirrorSource_t
{
  FROM_ONE = 1,
  FROM_TWO = 2
}

class MirrorA
{
  void one(int a) {  m_mirrrorListener.three(a, FROM_ONE); }
};

class MirrorB
{
  void two(int b) {  m_mirrrorListener.three(b, FROM_TWO); }
};

class MirrorListener
{
  void three(int c, mirrorSource_t source) { std::cout << c << " From " << source << std::endl; }
};

但是我们必须在需要新信息时更新三个的签名及其调用。

那么,如果我们有一个可以跟踪任意数量的消息的单例消息跟踪器(在其他类中称为 m_mirrorMessageTracker)会怎样?

enum mirrorSource_t
{
  FROM_ONE = 1,
  FROM_TWO = 2
}

class MirrorMessage
{
  public:
    MirrorMessage(mirrrorSource_t t) :  source(t)  {}
    get() { return source; }

  private:
    mirrorSource_t  source;
};

class MirrorMessageTracker {
public:

  MirrorMessage& MirrorMessageTracker::trackEvent(mirrorSource_t value)
  {
    trackedMessages.push_back(MirrorMessage(value));
    return trackedMessages.back();
  }

  MirrorMessage&  MirrorMesssageTracker::getCurrentEvent()
  {
    return trackedMessages.back();
  }

  static MirrorMessageTracker& getInstance()
  { 
    if(!m_Tracker)
    {
       m_pTracker = new MirrorMessageTracker();
    }
    return *m_pTracker; 
  }

private:
    MirrorMessageTracker() { }; //  
    static MirrorMessageTracker* m_pTracker;
    std::vector<MirrorMessage> trackedMessages;  // assumption is that tracked messages are
                                                 // single-threaded and unwind in a LIFO manner.
};

class MirrorA
{
  void one(int a)
  {
    MirrorMessage createdMessage = m_MirrorMessageTracker.trackMessage(FROM_ONE);
    m_mirrrorListener.three(a);
  }
};

class MirrorB
{
  void two(int b)
  {
    MirrorMessage createdMessage = m_MirrorMessageTracker.trackMessage(FROM_TWO);
    m_mirrrorListener.three(b);
  }
};

class MirrorListener
{
  void three(int c) 
  {
    MirrorMessage& message = m_MirrorMessageTracker.getCurrentMessage();
    if (message.get() == FROM_ONE)
    {
      std::cout << c << std::endl;
    }
    else if (message.get() == FROM_TWO)
    {
      std::cout << c << c << std::endl;
    }
    else
    {
      std::cout << c << c << c << std::endl;
    }
  }
};

我希望在 createdMessage 在第一和第二个范围之外之后从跟踪器中删除跟踪的消息。这可以通过特定类型的 boost 智能指针来完成吗?比如:

  std::vector<boost::shared_ptr<MirrorMessage> > trackedMessages;

vector::push_back 会创建消息的副本并将其放入向量中,因此我不确定是否可以使用共享指针。

【问题讨论】:

  • 对不起,MirrorMessageTracker& m_MirrorMessageTracker是MirrorA、MirrorB、MirrorListener中的一个变量。 MirrorA、MirroB 和 MirrorListener 的构造函数调用 getInstance()。
  • 只是简单地阅读,但是......你想创建一个堆栈跟踪生成器吗?
  • 那种。它更像是一种跟踪代码线程当前正在处理的事件类型的方法,而无需在线程内从一个函数传递到另一个函数。

标签: c++ raii


【解决方案1】:

更常见的创建单例的模式实际上是

  static MirrorMessageTracker& getInstance() { 
      static MirrorMessageTracker theMirrorMesageTracker;
      return theMirrorMesageTracker; 
  }

您还应该考虑通过对private 进行这些操作来禁止复制和分配MirrorMessageTracker 类:

  private:
      MirrorMessageTracker() { };
      MirrorMessageTracker(const MirrorMessageTracker&); // <<<
      MirrorMessageTracker& operator=(const MirrorMessageTracker&); // <<<

【讨论】:

  • 对不起,我在我的问题中搞砸了单例,因为我最关心的是在堆栈展开时处理从容器中清除跟踪事件的问题
  • 您忘记将单例实例设为静态。
  • @NeilKirk bTHX 发现了这个
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多