如何合并使用私有成员的不同类的相同方法

时间:2011-12-12 21:00:31

标签: c++ oop qt class-design

我刚刚在这里注册,所以在此之前,感谢阅读!

我正在使用Qt开发一个应用程序,但我需要一些关于共享类成员的建议。 我正在使用项目特定结构的一些集合(QHash),我创建了一个多态类来管理这些集合。派生类还管理一些UI组件(通过指针或引用共享),因此它可以自动表示UI中的那些结构。它是这样的:

主要课程

class ArmyEditor : public QMainWindow
{
//.... some specific functions ...

private:
    Ui::ArmyEditor *ui;

    // Specific structs
    QHash<QString, GameCategory> categories;
    QHash<QString, Column> columns;
    QHash<QString, GameProperty> properties;
    QHash<QString, UnitOption> commonOptions;
    QHash<QString, UnitOption> inheritedOptions;
    QHash<QString, GameItem> items;
    QHash<QString, GameItem> inheritedItems;
    QHash<QString, GlobalText> globalTexts;
    QHash<QString, GlobalText> inheritedGlobalTexts;
    QHash<QString, Unit> units;
};

集合管理的基类..

class StructManager : public QObject {
    Q_OBJECT
public:

    explicit StructManager(QWidget* parent = 0);

    // ...Functions that perform actions in shared components...

protected:
    QWidget *parent;
    QHash<QString, GameCategory> *categories;
    QHash<QString, Column> *columns;
    QHash<QString, GameProperty> *properties;
    QHash<QString, UnitOption> *commonOptions;
    QHash<QString, GameItem> *commonItems;
    QHash<QString, GlobalText> *globalTexts;
    QHash<QString, Unit> *units;
};

用于UI管理的派生类等等

class StructEditor : public StructManager
{
    Q_OBJECT
public:

    StructEditor(QWidget* parent = 0);

    // ...Overriden functions to automatically represent structs in the shared members..

protected:
    QTreeWidget *catList;
    QListWidget *colList;
    QTreeWidget *propList;
    QTreeWidget *optList;
    QListWidget *optActionList;
    QTreeWidget *itemList;
    QListWidget *itemActionList;
    QTableWidget *globalTextsGrid;
    QTreeWidget *unitTree;
    QComboBox *optCategory;
    QComboBox *itemCategory;
    QComboBox *unitCategory;
    QComboBox *optAmountColumn;
    QComboBox *optSetColumn;
};

我在MainWindow类的构造函数中共享一些UI成员..

ArmyEditor::ArmyEditor(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::ArmyEditor)
{
    ui->setupUi(this);

    // Setup Army Struct Manager

    armyManager = new StructEditor(this);

    armyManager->setCatList(ui->catList);
    armyManager->setOptList(ui->optList);
    armyManager->setOptActionList(ui->optActionList);
    armyManager->setItemList(ui->itemList);
    armyManager->setItemActionList(ui->itemActionList);
    armyManager->setGlobalTextsGrid(ui->globalTextsGrid);
    armyManager->setUnitTree(ui->unitTree);
    armyManager->setOptCategory(ui->optCategory);
    armyManager->setItemCategory(ui->itemCategory);
    armyManager->setUnitCategory(ui->unitCategory);
    armyManager->setOptAmountColumn(ui->optAmountColumn);
    armyManager->setOptSetColumn(ui->optSetColumn);
    armyManager->setCategories(&categories);
    armyManager->setOptions(&commonOptions);
    armyManager->setItems(&items);
    armyManager->setGlobalTexts(&globalTexts);

    //.. some other code ..
};

当我需要添加一个新类别或类似的东西时,我调用StructEditor类中的函数。 我的项目由三个应用程序组成,其中几个使用几乎相同的方法来管理这些结构,所以我决定使用一个带有方法的类来添加,更新,删除和表示UI中的结构,与MainWindow共享一些成员指针类。但现在我认为它有点脏,我不应该分享这些成员,因为MainWindow失去了对它们的控制权。我想我可以在Base类中创建我的结构集合并创建一个方法,这样我就可以在MainWindow类中读取(安全地)这些集合的成员,但我的问题在于UI成员。我可以直接在MainWindow类中使用信号并管理这些成员,但是我必须复制大量代码,这会使代码更改变得复杂(这是我决定将这些方法统一到一起的主要原因)。类。

所以,我的问题是:有没有办法在没有共享成员或使用全局变量的情况下“统一”这些方法(因为会产生相同的效果)?我想将这些方法放在一个单独的文件中。

谢谢和问候!

1 个答案:

答案 0 :(得分:0)

您应该查看您提供的继承以及数据所在的位置。

正如AJG85指出的那样,你应该将数据与操纵器分离并查看,例如:

class StructManager {
private:
    typedef QHash<QString, GameCategory> CategoryT;
    CategoryT categories;
    ....
public:
    CategoryT& getCategories() { return categories; }
};

class StructEditor : public QObject
{
Q_OBJECT
protected:
    StructManager sm;
...
};

class ArmyEditor : public StructEditor
{
public:
    <manipulation methods>
};

class ArmyWindow : public MainWindow
{
private:
    ArmyEditor ae;
....
};

一旦你遵循这个结构,你会发现来自UI的所有事件都可以传递给你的编辑器,这些编辑器操纵数据并显示读取它的字段。

这样,您就不会在对象和没有代码重复之间共享数据。如果你真的想要这样做:

class BaseEditor
{
protected:
    void ManipulateCategories() = 0;
};

class StructEditor : public QObject, public BaseEditor
{
   ....
};

class ArmyEditor : public QObject, public BaseEditor
{
 ....
};

我相信你可以找出各个编辑器类的实现。