Advice about sharing class members

Hi everybody.. Maybe this goes in "Beginners" XD

I'm developing an application using Qt, but I need some advices regarding sharing class members.
I am working with some collections (QHash) of project-specific structs and I created a polymorphic class to manage those collections. A derived class also manage some UI components (shared through pointers or references) so it can automatically represent those structs in the UI.. It's something like this:

Main class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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;
};


Base class for collection managing..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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;
};


Derived class for UI management and so on

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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;
};


And I share some UI members in the constructor of the MainWindow class..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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 ..
};


I call the functions from the StructEditor class when I need to add a new Category or something like that..
My project consists of three applications, those of which use almost the same methods for managing these structs, so I decided to use a class with the methods to add, update, remove and represent the structs in the UI sharing some member pointers with the MainWindow class. But now I'm thinking it is a bit dirty and I should not share these members because the MainWindow loses control over them. I was thinking I could create the collections of my structs in the Base class and make a method so I can read (securely) members of those collections in the MainWindow class, but my problem is with UI members. I could use signals and manage those members directly in the MainWindow class, but then I would have to duplicate a lot of code and it would complicate (a bit) the code changes, which is the main reason I decided to unify those methods in a class.

So, my question is: Is there any way to 'unify' those methods without having to share members or using ugly global variables? I would like to have those methods in a separated file.

Thanks and greetings!
No one? Please, I'm trying to find the best way to achieve this..

Thanks again!
What do you mean by "...MainWindow loses control over them."?

From what you wrote I think that you're saying that your "MainWindow" class is a 'friend' of your base class, and you don't want to have it structured that way?

What do you mean by "My project consists of three applications(sic?)..."? Do you actually have three different applications running for this one project? Or did you mean to say three threads?
Thanks for your answer.

Actually MainWindow is not a 'friend' of my base class. As for now, my MainWindow class has UI (inside the data pointed by ui) components like catList (QTreeWidget), colList (QListWidget) and many more, and I share their pointers with the StructEditor class (as I tried to represent with the latest piece of code). I just think it is not too good to share class private members because it is harder to notice the changes on that members (like with global variables) and I would like to replace such method with a better one (this is what I mean with "MainWindow loses control over them". But I need to do almost the same thing with three files and I wouldn't like to be redundant with my code because it would make difficult or "less error-proof" with updates..

I have three applications which share almost the same base. My main program performs some actions acording to the data of files of two types: Game File and Army File. I have another program for creating Game Files and another one for Army Files. This results in three applications: Game File Writer, Army File Writer and Reader (both Game Files and Army Files).

Thanks again!
This might be a tough one to answer without going through your code line by line (which to be honest I wouldn't actually do). It seems to me that the solution might be to make the three applications you have into one, that way you only have the one base class. Don't forget you can virtualize any functions that don't work exactly the same between classes.
I just want to keep all these methods in a different (hopefully unique) file, no matter if they're really definitions of private functions of the MainWindow class. The thing is I would like to use them in different classes. I was thinking I could use macros with something like this:

1
2
3
4
5
#define CLASS ArmyEditor

CLASS::exampleFunction() {
  //.. code ..
}


But probably it makes the code less readable (and I'm working in an open source project). I don't know if templates and inheritance can help in some way.

I can't join the three applications because at least one works very different. The other two could be merged into one program, but anyway I would have to repeat code in at least two files. As for now I use virtual functions in the Base class, but I am sharing the members of the MainWindow class and that's exactly what I'm trying to avoid. Qt has signals, which could be used to solve that problem very easily, but they don't solve the 'redundant code' problem.

Thanks again!
No, do NOT use Macros like that. In the beginning you said that you were making a polymorphic class, I know it gets a little crazy at times but you should just stick with that idea.

Don't take offence to this question, but what is your skill level? Some things in your last post have me wondering if I should tone it down a bit.
Yes, I know. That was just a desperate option. I knew that macro option would you let think I am very novice.

Really I don't know what to answer regarding my skill level. I have worked in some C++ projects but this is the biggest one. I have something like a year of experience in C++ and 3 or 4 years in programming.

I like how the polymorphic class is working for me, but I'm just not sure if sharing class member pointers is a good idea.

Thanks and greetings!
I was wondering if it would be better to share a reference to the UI widgets only when I need to modify them rather than storing pointers. How good is it?

For example:

Actual code..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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;
};


New code..

1
2
3
4
5
6
7
8
9
10
class StructEditor : public StructManager
{
    Q_OBJECT
public:
 
    StructEditor(QWidget* parent = 0);
 
    // ...Overriden functions to automatically represent structs in the shared members..
    addCategory(QTreeWidget& catList); // Just example.. More arguments should be here.
};
Topic archived. No new replies allowed.