【问题标题】:Static QList of QObject pointers to keep track of siblings?QObject 指针的静态 QList 以跟踪兄弟姐妹?
【发布时间】:2014-06-06 21:54:21
【问题描述】:

我想通过将this(指向自身的指针)附加到“共享”静态QList 类成员来跟踪thisClass(继承QObject)实例(“兄弟姐妹”):

private:
  static QList<thisClass*> _plist;

但是,static 成员声明会导致 LNK2001 无法解析的外部符号。如果没有static,程序会构建(但每个对象只有自己的数据)。

什么可能导致错误,是否有解决方法,以及“跟踪类实例”应该如何正确完成?

【问题讨论】:

标签: c++ qt list pointers static-members


【解决方案1】:

你已经声明了静态成员。现在你需要在 cpp 文件中定义它:

QList&lt;thisClass*&gt; thisClass::_plist;

【讨论】:

    【解决方案2】:

    你所做的只是一个声明,你还需要定义成员变量。这是在您的一个源文件中完成的。

    【讨论】:

      【解决方案3】:

      如果您不需要列表的随机访问迭代,您还可以使用侵入式容器来允许兄弟节点的迭代:它的开销较低,因为列表节点存储在对象本身中。该列表可以像 std::list 一样进行迭代,它跟踪对象的动态生命周期 - 它与 QPointer 没有什么不同,只是它是一个列表。

      // myclass.h - interface
      #include <QObject>
      #include <boost/intrusive/list.hpp>
      class MyClass : public QObject, private boost::intrusive::list_base_hook<> {
        using list_t = boost::intrusive::list<MyClass>;
        static list_t m_siblings;
        friend list_t;
        static QThread const *listThread() {
          return m_siblings.empty() ? QThread::currentThread() : m_siblings.front().thread();
        }
      protected:
        bool event(QEvent * ev) override {
          if (ev->type() == QEvent::ThreadChange)
            Q_ASSERT(m_siblings.size() <= 1);
          return QObject::event(ev);
        }
      public:
        MyClass(QObject *parent = {}) : QObject{parent} {
          Q_ASSERT(listThread() == QThread::current_thread());
          m_siblings.push_back(*this);
          qDebug() << "there are" << m_siblings.size() << "objects in existence";
        }
        ~MyClass() override {
          m_list.erase(m_siblings.iterator_to(*this));
        }
      };
      
      // myclass.cpp - implementation
      #include "myclass.h"
      boost::intrusive::list<MyClass> MyClass::m_siblings;
      

      强制所有兄弟姐妹都在同一个线程中;这对于列表的线程安全访问是必要的。如果对象存在于任意线程中,则列表访问需要由互斥体保护:

      // myclass.h - interface
      #include <QObject>
      #include <boost/intrusive/list.hpp>
      class MyClass : public QObject, private boost::intrusive::list_base_hook<> {
        using list_t = boost::intrusive::list<MyClass>;
        static QReadWriteLock m_siblingsMutex;
        static list_t m_siblings;
        friend list_t;
      public:
        MyClass(QObject *parent = {}) : QObject{parent} {
          QWriteLocker lock(&m_siblingsMutex);
          m_siblings.push_back(*this);
        }
        ~MyClass() override {
          QWriteLocker lock(&m_siblingsMutex);
          m_siblings.erase(m_siblings.iterator_to(*this));
        }
        void dumpSiblings() {
          QReadLocker lock(&m_siblingsMutex);
          for (auto const &obj : m_siblings)
             qDebug() << "MyClass at " << &obj;
      };
      
      // myclass.cpp - implementation
      #include "myclass.h"
      QReadWriteLock MyClass::m_siblingsMutex;
      boost::intrusive::list<MyClass> MyClass::m_siblings;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-05-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-08-29
        • 1970-01-01
        • 1970-01-01
        • 2015-03-06
        相关资源
        最近更新 更多