Resolver errores de compilación debido a la dependencia circular entre clases


A menudo me encuentro en una situación en la que me enfrento a múltiples errores de compilación/enlace en un proyecto de C++ debido a algunas malas decisiones de diseño (hechas por otra persona :) ) que conducen a dependencias circulares entre clases de C++ en diferentes archivos de encabezado (puede ocurrir también en el mismo archivo). Pero afortunadamente(?) esto no sucede lo suficientemente a menudo como para que recuerde la solución a este problema para la próxima vez que vuelva a suceder.

Así que para los propósitos de fácil recuperación en el futuro Voy a publicar un problema representativo y una solución junto con él. Por supuesto, las mejores soluciones son bienvenidas.


  • A.h

    class B;
    class A
    {
        int _val;
        B *_b;
    public:
    
        A(int val)
            :_val(val)
        {
        }
    
        void SetB(B *b)
        {
            _b = b;
            _b->Print(); // COMPILER ERROR: C2027: use of undefined type 'B'
        }
    
        void Print()
        {
            cout<<"Type:A val="<<_val<<endl;
        }
    };
    

  • B.h

    #include "A.h"
    class B
    {
        double _val;
        A* _a;
    public:
    
        B(double val)
            :_val(val)
        {
        }
    
        void SetA(A *a)
        {
            _a = a;
            _a->Print();
        }
    
        void Print()
        {
            cout<<"Type:B val="<<_val<<endl;
        }
    };
    

  • main.cpp

    #include "B.h"
    #include <iostream>
    
    int main(int argc, char* argv[])
    {
        A a(10);
        B b(3.14);
        a.Print();
        a.SetB(&b);
        b.Print();
        b.SetA(&a);
        return 0;
    }
    

Warning: Undefined property: agent_blog_content::$date_asked in /var/www/agent_etc/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 32

Warning: Undefined property: agent_blog_content::$count_answers in /var/www/agent_etc/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 52