如何使一个系统(SystemB1)访问另一个系统的字段(SystemA::sub),就好像它是它自己的字段一样?

  • SystemA是一个具有自己的字段Sub* sub的实用程序系统。
  • SystemB1-SystemB5是想要轻松访问SystemA::sub的系统。
  • 还有其他系统,但是与SystemA或任何SystemB不相关。 (未显示)

  • 这是一个有效的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()` ?
    }
    

    注意:-(以防相关)
  • 在实际情况下,它使用服务定位器模式(1个系统〜1个服务),并且Sub1* sub1不是指针,但具有operator->()
  • 实际上,Sub1是丑陋的模板类型,例如Sub<std::unordered_map<EnemyShip,Turret>>。因此,引用sub1类型(如果需要)的最方便方法是使用decltype



  • 是否有任何设计模式/ C++魔术(宏除外)将systemA->sub1->f();缩写为sub1->f();等较短的代码?

    抱歉,这似乎是一个非常琐碎的问题。
    我想提高自己的技能和生产力-每件事都会有所帮助。

    我可怜的解决方案

    我发现的唯一解决方案是为名为SystemB1,B2,...SystemB创建类。
    //need #include SystemA
    class SystemB : public Core{
        //Solution 1 : cached from SystemA's
        public: decltype(SystemA::sub1.operator->()) sub1;
        //  decltype(SystemA::sub2.operator->()) sub2;
    
        //Solution 2 :
        public:  decltype(SystemA::sub1.operator->()) getSub1();
        // decltype(SystemA::sub2.operator->()) getSub2();
    };
    

    然后,SystemB1,B2...将能够直接调用sub1->f1()getSub1()->f1()

    劣势:
  • 每当我将新的subX添加到SystemA时:-
  • (解决方案1)我必须创建一个新字段SystemB::subX并使用正确的指针进行设置。
  • (解决方案2)我必须添加具有正确实现的SystemB::getSubX()
  • 非常难看。 decltype是必需的,因为如果我在Sub1* sub1中声明SystemB:-
  • 每当我更改SystemA::sub1的类型时,例如从Sub<std::unordered_map<EnemyShip,Turret>>Sub<std::unordered_map<EnemyShip,Tracker>>中的SystemA,我还必须更改字段类型或SystemB中的函数返回类型,这会引起一些可维护性问题。
  • 最佳答案

    class SystemA : public Core
    {
    public:
        Sub1 *sub1 = new Sub1();
        //has 5-10 subsystems (Sub1 Sub2 Sub3 ...)
        static SystemA &GetInstance();
    };
    
    SystemA &SystemA::GetInstance()
    {
        static SystemA sa;
        return sa;
    }
    
    //"SystemB1.h"
    class SystemB1 : public Core
    {
    private:
        SystemA *systemA;
    public:
        void SystemB1()
        {
            // use this
            systemA = new SystemA(...);
            // or this
            systemA = &SystemA::GetInstance();
        }
        void fB1();
    };
    
    //"SystemB1.cpp" , include "SystemA.h"
    void SystemB1::fB1()
    {
        systemA->sub1->f(); //<--- Can it be more concise like `sub->f()` ?
    }
    

    第一个对象SystemA始终使用GetInstance调用来创建。

    例如:
    SystemA *m_mainSystem = &SystemA::GetInstance();
    

    另外,看看在c++ FFmpeg上编写的系统代码。

    10-02 07:31