How to enable a system (SystemB1
) to access a field of another system (SystemA::sub
) as if it is its own field?
SystemA
is a utility system with its own fieldSub* sub
.SystemB1
-SystemB5
are systems that want to accessSystemA::sub
easily.- There are other systems, but it is not related to
SystemA
or anySystemB
. (not shown)
Here is a working MCVE.
class SystemA;
class SystemB1;
class Core{
public:
SystemA* systemA=nullptr;
SystemB1* systemB1=nullptr;
//SystemB2,B3,B4,B5
};
//"SystemA.h"
class Sub1{
public: void f(){std::cout<<"OK"<<std::endl;}
//has 10-20 function
};
class SystemA : public Core{
public: Sub1* sub1=new Sub1();
//has 5-10 subsystems (Sub1 Sub2 Sub3 ...)
};
//"SystemB1.h"
class SystemB1 : public Core{
public: void fB1();
};
//"SystemB1.cpp" , include "SystemA.h"
void SystemB1::fB1(){
systemA->sub1->f(); //<--- Can it be more concise like `sub->f()` ?
}
Note :- (just in case it is related)
- In real case, it uses service locator pattern (1 system ~ 1 service) and
Sub1* sub1
is not a pointer but hasoperator->()
. - In real case,
Sub1
is an ugly template type e.g.Sub<std::unordered_map<EnemyShip,Turret>>
. Thus the most convenient way to refer to type ofsub1
(if needed) is to usedecltype
.
Question
Are there any design pattern / C++ magic (except macro) to abbreviate systemA->sub1->f();
to something shorter like sub1->f();
?
Sorry if it seems to be a very trivial question.
I want to improve my skill and productivity - every little thing can help.
My poor solution
The only solution I found is to create a base class for SystemB1,B2,...
named SystemB
.
class SystemB : public Core{
public: Sub1* sub1; Sub2* sub2; ... (solution 1)
//or alternative ....
public: Sub1* getSub1(); Sub2* getSub2(); ...(solution 2)
//^ e.g. return systemA->sub1
};
Then, SystemB1,B2...
will be able to call sub1->f1()
or getSub1()->f1()
directly.
Disadvantage:
-
Whenever I add a new
subX
toSystemA
:-- (Solution 1) I have to create a new field
SystemB::subX
and set it with a correct pointer. - (Solution 2) I have to add
SystemB::getSubX()
with correct implementation.
- (Solution 1) I have to create a new field
-
Whenever I change type of
sub
e.g. fromSub<std::unordered_map<EnemyShip,Turret>>
toSub<std::unordered_map<EnemyShip,Tracker>>
inSystemA
:-- I have to also change type of field or return type of function in
SystemB
OR
usedecltype(SystemA::sub1)
(but it requiresSystemB.h
to #includeSystemA.h
)
- I have to also change type of field or return type of function in
These may cause some maintainability problem.
Aucun commentaire:
Enregistrer un commentaire