473,412 Members | 2,096 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,412 software developers and data experts.

How to merge the same method of different classes in the clean way

Hi everybody..

I'm developing an application using Qt, but I need some about how to avoid code repeat without sharing the private members of my class.
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

Expand|Select|Wrap|Line Numbers
  1. class ArmyEditor : public QMainWindow
  2. {
  3. //.... some specific functions ...
  4.  
  5. private:
  6.     Ui::ArmyEditor *ui;
  7.  
  8.     // Specific structs
  9.     QHash<QString, GameCategory> categories;
  10.     QHash<QString, Column> columns;
  11.     QHash<QString, GameProperty> properties;
  12.     QHash<QString, UnitOption> commonOptions;
  13.     QHash<QString, UnitOption> inheritedOptions;
  14.     QHash<QString, GameItem> items;
  15.     QHash<QString, GameItem> inheritedItems;
  16.     QHash<QString, GlobalText> globalTexts;
  17.     QHash<QString, GlobalText> inheritedGlobalTexts;
  18.     QHash<QString, Unit> units;
  19. };
Base class for collection managing..

Expand|Select|Wrap|Line Numbers
  1. class StructManager : public QObject { // Base class
  2.     Q_OBJECT
  3. public:
  4.  
  5.     explicit StructManager(QWidget* parent = 0);
  6.  
  7.      virtual bool addCategory(const GameCategory &category, const QString &key);
  8.      // ..More virtual functions...
  9. protected:
  10.     QWidget *parent;
  11.     QHash<QString, GameCategory> *categories; // Shared members
  12.     QHash<QString, Column> *columns;
  13.     QHash<QString, GameProperty> *properties;
  14.     QHash<QString, UnitOption> *commonOptions;
  15.     QHash<QString, GameItem> *commonItems;
  16.     QHash<QString, GlobalText> *globalTexts;
  17.     QHash<QString, Unit> *units;component
  18.     // There are more here
  19. };
Expand|Select|Wrap|Line Numbers
  1. bool StructManager::addCategory(const GameCategory &category, const QString &key) {
  2.     if(categories && GameStructs::isValidKey(key, parent)) {
  3.         if(!categories->contains(key)) {
  4.             categories->insert(key, category);
  5.             emit categoryAdded(category, key);
  6.             return true;
  7.         } else {
  8.             if(showMessages)
  9.                 QMessageBox::critical(parent, tr("Can not add the category"), tr("The category can not be added because its ID (%1) already exists").arg(key));
  10.             return false;
  11.         }
  12.     } else
  13.         return false;
  14. }
Derived class for UI management and so on

Expand|Select|Wrap|Line Numbers
  1. class StructEditor : public StructManager
  2. {
  3.     Q_OBJECT
  4. public:
  5.  
  6.     StructEditor(QWidget* parent = 0);
  7.     virtual bool addCategory(const GameCategory &category, const QString &key);
  8.     // ...More overriden functions...
  9.  
  10. protected:
  11.     QTreeWidget *catList; // More shared items (there are get/set methods in the class)
  12.     QListWidget *colList;
  13.     QTreeWidget *propList;
  14.     QTreeWidget *optList;
  15.     QListWidget *optActionList;
  16.     QTreeWidget *itemList;
  17.     QListWidget *itemActionList;
  18.     QTableWidget *globalTextsGrid;
  19.     QTreeWidget *unitTree;
  20.     QComboBox *optCategory;
  21.     QComboBox *itemCategory;
  22.     QComboBox *unitCategory;
  23.     QComboBox *optAmountColumn;
  24.     QComboBox *optSetColumn;
  25. };
Code snippet

Expand|Select|Wrap|Line Numbers
  1. bool StructEditor::addCategory(const GameCategory &category, const QString &key) {
  2.     if(catList && StructManager::addCategory(category, key)) {
  3.         QStringList cells;
  4.         cells << QString(category.getName());
  5.         QTreeWidgetItem* item = new QTreeWidgetItem(cells);
  6.         item->setData(0, Qt::UserRole, key);
  7.         catList->topLevelItem(category.type)->addChild(item);
  8.         catList->expandItem(catList->topLevelItem(category.type));
  9.  
  10.         if(category.type == GameCategory::CategoryOfOptions) {
  11.             if(optList && optCategory) {
  12.                 item = new QTreeWidgetItem(cells);
  13.                 item->setData(0, Qt::UserRole, key);
  14.                 optList->addTopLevelItem(item);
  15.                 optCategory->addItem(category.getName(), key);
  16.             }
  17.         } else if(category.type == GameCategory::CategoryOfItems) {
  18.             if(itemList && itemCategory) {
  19.                 item = new QTreeWidgetItem(cells);
  20.                 item->setData(0, Qt::UserRole, key);
  21.                 itemList->addTopLevelItem(item);
  22.                 itemCategory->addItem(category.getName(), key);
  23.             }
  24.         } else if(unitCategory && unitTree && category.type == GameCategory::CategoryOfUnits) {
  25.             item = new QTreeWidgetItem(cells);
  26.             item->setData(0, Qt::UserRole, QVariant(key));
  27.             unitTree->addTopLevelItem(item);
  28.             unitCategory->addItem(category.getName(), key);
  29.         }
  30.         return true;
  31.     } else
  32.         return false;
  33. }
  34.  
And I share some UI members in the constructor of the MainWindow class..

Expand|Select|Wrap|Line Numbers
  1. ArmyEditor::ArmyEditor(QWidget *parent) :
  2.     QMainWindow(parent),
  3.     ui(new Ui::ArmyEditor)
  4. {
  5.     ui->setupUi(this);
  6.  
  7.     // Setup Army Struct Manager
  8.  
  9.     armyManager = new StructEditor(this);
  10.  
  11.     armyManager->setCatList(ui->catList);
  12.     armyManager->setOptList(ui->optList);
  13.     armyManager->setOptActionList(ui->optActionList);
  14.     armyManager->setItemList(ui->itemList);
  15.     armyManager->setItemActionList(ui->itemActionList);
  16.     armyManager->setGlobalTextsGrid(ui->globalTextsGrid);
  17.     armyManager->setUnitTree(ui->unitTree);
  18.     armyManager->setOptCategory(ui->optCategory);
  19.     armyManager->setItemCategory(ui->itemCategory);
  20.     armyManager->setUnitCategory(ui->unitCategory);
  21.     armyManager->setOptAmountColumn(ui->optAmountColumn);
  22.     armyManager->setOptSetColumn(ui->optSetColumn);
  23.     armyManager->setCategories(&categories);
  24.     armyManager->setOptions(&commonOptions);
  25.     armyManager->setItems(&items);
  26.     armyManager->setGlobalTexts(&globalTexts);
  27.  
  28.     //.. some other code ..
  29. };
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!
Dec 14 '11 #1
4 1982
weaknessforcats
9,208 Expert Mod 8TB
You are aware that there are no classes in C++?

All you have are structs to corral members. That means your structs need constructors, destructors, methods, etc.

The class was added to make C++ look like it as object-oriented. But underneath the class is implemented as a struct.

The only dfference between a class and a struct is the default access. A struct is public. A class is private.

Also, there should be no passing pointers around a C++ program. You have to use handles (managed pointers for this). Otherwise there is simply no way to be sure that the pointer contains a valid address.

How can you have a code repeat trying to share a private member of a class when rivate members are not sharable. Doing so breaks encapsulation and data hiding and leads to spaghetti code. Could you post an example of this?
Dec 15 '11 #2
Sharing private members was a way to avoid code repeat. If a hadn't "bool StructEditor::addCategory(const GameCategory &category, const QString &key)", I would have to create that method in each class I want to use. This method uses some pointers like catList, which I set in ArmyEditor constructor.

Someone gave me an option using templates (in a new base class, an then ArmyEditor should inherit from it), and it seems to be the cleanest way to achieve what I'm trying to do.

I can post the entire code if it is needed, but it is too large and you probably will just ignore it.

Greetings!
Dec 15 '11 #3
weaknessforcats
9,208 Expert Mod 8TB
It may be there is a confusion between the interface and the implementation. Classes that are missing methods may compensate by using Visitors and Decorators.

I wrote an article about Visitors in the C/C++ Insights forum.

True, I may not read your entire code but your Class Diagram would be interesting.
Dec 15 '11 #4
Probably it has terrible design flaws, but I'm trying to correct them. Here is the link to the entire project: http://code.google.com/p/yalb/downlo...r.zip&can=2&q=

I also attached some files missing to the project actually compile,.

I will read your article.

Thanks and greetings!
Attached Files
File Type: zip propertyform.h.zip (3.4 KB, 61 views)
Dec 15 '11 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

6
by: Pedro Alves | last post by:
Hi I'm having serious problems with a mission critical app that runs on postgres (and has been running for the past 3 years). It's rather large, and lately things are not going well. The...
5
by: sql-db2-dba | last post by:
We have DB2 UDB v8.1 fixpak3 on AIX 5. Production and Development configuarations (at least for DB2) are identical albeit production is a 2-way server while development has only one processor....
1
by: Jeroen Ceuppens | last post by:
Hi, I want to to include the same function in 2 different classes. class FormView.cs and FormLoad.cs, 2 of Windows.Forms these 2 classes have a couple of the same methods, what is the best way to...
3
by: Mungo Jerrie | last post by:
Hi there :-) I have some problems with the same instance of my xmldocument across 3 different classes. See code below: class one { protected static XmlDocument doc = new XmlDocument(); ...
4
by: MikeAth via DotNetMonster.com | last post by:
Hi all, I have two different classes and one instance of the Form. I would like to access the members of the Form instance in both classes without having to create a new instance in the other...
1
by: Rico Rivera | last post by:
I have two files: FileA.vb FileB.vb FileA.vb contains the following sample code: NameSpace SomeNamespace Public Class SomeClassA Public Shared Function MethodA() As String
7
by: Ron | last post by:
Hello, I have 4 classes that use 4 DTS packages on 4 different tables. So I have Dim cls1 As New clsDTS1, cls2 As New clsDTS2 Dim cls3 As New clsDTS3, cls4 As New clsDTS4 Each class has a...
3
by: Bruce Wood | last post by:
Maybe I'm going nuts, but I was so sure that adding the same method more than once to a delegate would result in only one entry on the delegate's call list: this.UpdateEnd += new...
3
by: juro | last post by:
Hi, I have a small problem: I'd like to call static variables from different classes - their names are stored in an array. Example of a class: class MyClass1{ public static $mysql_table =...
7
by: Peter Laan | last post by:
Is there a simple way to encapsulate the functionality to redo a method call a second time in case a specific exception is thrown? We are sending commands to an external system and if the sessionId...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.