viernes, 23 de noviembre de 2012

Resolviendo dependencias circulares en c++ con forward declaration

El problema de las dependencias circulares aparece en el momento en que dos clases distintas tienen una instancia o hacen referencia a la otra en su declaración.

Como ejemplo estas dos clases, las cuales tienen un puntero a una instancia de la otra:

class_a.h

#ifndef CLASS_A_H_
#define CLASS_A_H_

#include "class_b.h"

class ClassB; // Commenting this line compilation will fail

class ClassA
{
public:
 ClassA();

private:
 ClassB * b;
};

class_b.h

#ifndef CLASS_B_H_
#define CLASS_B_H_

#include "class_a.h"

class ClassA; // Commenting this line compilation will fail

class ClassB
{
public:
 ClassB();

private:
 ClassA * a;
};

En este caso hasta que una de las clases no haya sido totalmente interpretada por el compilador, éste no podrá interpretar la otra. Lo que hace que el compilador se queje de no conocer el objeto.

Para solucionar este problema se debe indicar al compilador en ClassB que ClassA es una clase, y lo mismo para la ClassA. A esta declaración "anticipada" se la llama "Forward declaration" (ver Wikipedia: Forward declaration).

En el código de arriba este problema está solucionado, pero si quereis reproducir el error comentar la linia que esta indicada.

Aqui teneis el resto de ficheros necesarios para hacer una prueba:

main.cpp

#include "class_a.h"
#include "class_b.h"

int main()
{
 ClassA a;
 ClassB b;

 return 0;
}

class_a.cpp

#include "class_a.h"
#include "cstdio"

ClassA::ClassA() {
 printf("Creating ClassA object\n");
}

class_b.cpp

#include "class_b.h"
#include "cstdio"

ClassB::ClassB() {
 printf("Creating ClassB object\n");
}

Para compilarlo todo:

Makefile

all: main

main: main.o class_a.o class_b.o
 g++ -o main main.o class_a.o class_b.o

main.o: main.cpp
 g++ -c main.cpp

class_a.o: class_a.cpp
 g++ -c class_a.cpp
 
class_b.o: class_b.cpp
 g++ -c class_b.cpp

clean: 
 rm -f *.o main

Ver explicación más detallada en la fuente : Stackoverflow

No hay comentarios:

Publicar un comentario