C ++ how to create classes that are interdependent

I have a storage class. members of this class often change. every time an element is changed, I would like to save the state of the class (an instance of the clone class and save it). Therefore, I would like to create a new class that preserves these states.

Example:

Say I have a storage class in storage.h

class Storage { public: Int m_cnt; <lots of other members...> StorageHistory m_his; }; 

and the StorageHistory class in storagehistory.h

 class StorageHistory { public: std::vector<Storage> m_history_vec; }; 

Assumptions:

  • Class
  • StorageHistory must be stored in the storage class. the reason is that the Storage class is the main class that can be accessed in all classes / packages. To minimize code changes, I would like S torageHistory be associated with the Storage class.
  • StorageHistory cannot be static or single, as multiple Storage instances are created.

Problems:

  • Unable to compile this code. storage.h must be compiled before storagehistory.h and vice versa
  • If StorageHistory cannot be stored in the Storage class, then should I save it? who owns this class?

Need help identifying the relationship between the two classified?

+4
source share
4 answers

First of all: do not make data members publicly available unless you define a clean data structure. Then: Int not a C ++ type.

Now for your questions: you can use forward ads. Since StorageHistory used directly in Storage , it cannot be declared forward, but Storage used only in the template data element (namely a std::vector ) in StorageHistory , and this template does not require the definition of Storage if it is declared only as a variable. You need a definition only when using vector methods.

So here is the loose code:

StorageHistory.h

 #include <vector> class Storage; class StorageHistory { std::vector<Storage> m_history_vec; public: /* method declarations */ }; 

Storage.h

 #include "StorageHistory.h" class Storage { int m_cnt; /* <lots of other members...> */ StorageHistory m_his; public: /* method declarations */ }; 

Storage.cpp

 #include "Storage.h" #include "StorageHistory.h" //not necessarily needed, because implicitly included, but thats a matter of coding style /* ... Storage methods definitions ... */ void Storage::changeVar(/*...*/) { m_his.push_back(*this); /* ... */ } 

StorageHistory.cpp

 #include "StorageHistory.h" #include "Storage.h" /* ... StorageHistory method definitions ... */ 
+1
source

Add to your header files

Storage.h

 class Storage; //to declear the class before the include #include "StorageHistory.h" //continue with the old declearation class Storage{ .... } 

and

StorageHistory.h

 class StorageHistory; //to declear the class before the include #include "Storage.h" //continue with the old declearation class StorageHistory{ .... } 

remember that first include defenders in files.

This can be done for all classes to avoid such a problem in the future.

+1
source

Basically you make memento design template. Your current compilation problems will disappear with the forward declaration. But for better design and implementation, you can see this and this .

0
source

You need to use forward announcements to work your solution. The easiest way is to put these classes in the same header file (but it can be solved somewhat differently):

 class StorageHistory; // *** Forward declaration *** class Storage { public: Int m_cnt; &lt;lots of other members...&gt; StorageHistory m_his; }; class StorageHistory { public: std::vector<Storage> m_history_vec; }; 

I do not like your decision. M_his will contain a list of storage classes, and all of them will contain a list of storage classes (albeit empty).

I would create a singleton with a storage vector map and wrap the storage with a container containing a UID.

 class StorageContainer { private: static int nextUID = 0; int uid; Storage data; public: StorageContainer() { uid = nextUID++; // Watch out for concurrency problems } Storage & GetData() { return data; } }; 

Then you can access the repository history by its UID.

 class StorageHistory { // The usual singleton stuff private: std::unordered_map<int, std::vector<Storage>> history; public: std::vector<Storage> & operator[] (int uid) { auto iter = history.find(uid); if (iter == unordered_map::end) { std::vector<Storage> newHistory; history[uid] = newHistory; } return history[uid]; } }; 
0
source

Source: https://habr.com/ru/post/1481879/


All Articles