Qt中的星系统数据结构实现

时间:2014-04-09 13:14:56

标签: c++ qt data-structures

我试图实现一个有用的数据结构来建模星系统。有人告诉我,树木结构可能是最好的,但是std和Qt都不具备那些开箱即用的结构。

到目前为止,我一直在使用以下类似的东西来制作天体与它们的轨道器:

typedef struct Body {
   /* various data*/
   QList<Body> orbiters;
} Body;

这很有用,因为它可以让我快速访问特定身体的轨道。然而,它不允许我确定,只是有问题的对象,身体在轨道运行!是否可以添加某种&#34;父指针&#34;到上面来实现那个?

2 个答案:

答案 0 :(得分:2)

这是一个简单的树实现,基于Qt object model(所有QObject都能够形成树)

class Body {
public:
    // When a Body is constructed, it automatically remembers its parent
    // and adds itself to its parent's list of children.
    Body(const QString& name, Body* parent = nullptr) {
        this->m_name = name;
        this->m_parent = parent;
        if (parent != nullptr) {
            parent->m_orbiters.append(this);
        }
    }

    // When a parent is deleted, the children are automatically deleted too.
    // If you use shared pointers, you don't need this destructor.
    ~Body() {
        qDeleteAll(m_orbiters);
    }

    // Getters
    QString name() const           { return m_name;     }
    Body* parent() const           { return m_parent;   }
    QList<Body*> children() const  { return m_orbiters; }

private:
    QString m_name;
    Body* m_parent;
    QList<Body*> m_orbiters;
};

建树:

// The sun doesn't orbit anything
Body* sun = new Body("Sun");

// The planets orbit the sun
Body* mercury = new Body("Mercury", sun);
Body* earth   = new Body("Earth",   sun);
Body* mars    = new Body("Mars",    sun);

// The moons orbit the planets
Body* moon   = new Body("Moon",   earth);
Body* phobos = new Body("Phobos", mars);
Body* deimos = new Body("Deimos", mars);

打印直接围绕太阳环绕的物体列表:

auto planets = sun->children();
for (Body* planet : planets) {
    qDebug() << planet->name();
}
// Output:
//  "Mercury"
//  "Earth"
//  "Mars"

删除树:

// The sun's destructor deletes the planets;
// the planets' destructor deletes the moons
delete sun; 

顺便说一句,听起来你对数据结构和指针没有多少经验。我建议你阅读一篇关于这两个主题的好教程/书籍 - 结果你的C ++生活会变得容易得多。

答案 1 :(得分:1)

QObject基于层次结构:引用该链接

  

QObjects在对象树中组织自己。当您使用另一个对象作为父对象创建QObject时,该对象将自动将其自身添加到父对象的children()列表中。父母取得对象的所有权;即,它将自动删除其析构函数中的子项。您可以按名称查找对象,也可以使用findChild()或findChildren()进行键入。

然后我建议改变你的类,继承自QObject:

class Body : public QObject {
Q_OBJECT
public:
    Body(QString name, QObject *parent = 0) : QObject(parent) {
      setObjectName(name);
   }
   /* keep orbiters in children(), find them by name */
   /* parent() give you the relation you're missing now... */
   ...
};

更改后,您将获得一个良好的对象系统的所有好处,以及通过信号/插槽等进行高级通信的好处......