簡體   English   中英

靜態QList的QObject指針來跟蹤兄弟姐妹嗎?

[英]Static QList of QObject pointers to keep track of siblings?

我想通過this (指向self的指針)附加到“共享的”靜態QList類成員thisClass跟蹤thisClass (繼承QObject)實例(“兄弟”):

private:
  static QList<thisClass*> _plist;

但是, static成員聲明會導致LNK2001無法解析的外部符號。 如果沒有static ,則程序會生成(但是每個對象只有自己的數據)。

可能導致該錯誤的原因是什么,是否有修復程序,以及如何正確完成“跟蹤類實例”?

您已聲明靜態成員。 現在您需要在cpp文件中定義它:

QList<thisClass*> thisClass::_plist;

您所做的只是一個聲明 ,還需要定義成員變量。 這是在您的一個源文件中完成的。

如果不需要列表的隨機訪問迭代,則還可以使用侵入式容器來允許兄弟姐妹進行迭代:由於列表節點存儲在對象本身中,因此開銷較低。 該列表可以像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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM