Pregunta

Buenas noches:)

Estoy jugando con g ++ y archivos make. He llegado a este punto:

foo.h:

#ifndef _FOO_H_
#define _FOO_H_

#include "bar.h"

class foo {
private:
    bar something;
public:
    bool start();
    bool stop();
};

#endif // _FOO_H_

foo.h es finalmente incluido en mi archivo principal CPP para que pueda poner las cosas en movimiento, llamando arranque / parada.

void somewhere() {
    foo* hihi = new foo;
    hihi->start();
    delete hihi;
}

Luego está bar.h:

#ifndef _BAR_H_
#define _BAR_H_

class bar {

};

#endif // _BAR_H_


g ++ no parece que les gusta sin embargo:

g++  (some_flags) -c main.cpp
In file included from main.cpp:2:
foo.h:8: error: ‘bar’ does not name a type

Estoy usando archivos make, y trató de una combinación de cosas como:

main.o: main.cpp foo.h bar.h

A pesar de que yo no creo que tenga que añadir bar.h aquí, no debería incluirla en foo.h será suficiente?

Para aclarar, esto es más o menos la forma en que está establecido ahora (sí sé que esto se puede hacer de una manera más eficiente):

main.o: main.cpp foo.h
    $(CC) $(CFLAGS) -c main.cpp

foo.o: foo.h foo.cpp
    $(CC) $(CFLAGS) -c foo.cpp

bar.o: bar.h bar.cpp
    $(CC) $(CFLAGS) -c bar.cpp

¿Qué está pasando? Calculo que es algo que me falta acerca g ++ y la forma en que maneja cabecera incluye, me punto en la dirección correcta por favor!

editar - encontrado la solución:

Doh! Me siento tonto en este momento. Fue jugar un poco con impulso :: asio y tipo de olvidado que todavía queda esta en la parte superior de mis encabezados de alguna parte: usando ASIO impulso :: :: :: TCP IP;

Digamos que hay un impulso :: asio :: :: ip tcp función :: bar: D

Bueno, gracias de todos modos!

¿Fue útil?

Solución

  

Se ha de jugar un poco con el impulso :: asio y tipo de olvidado que todavía queda esta en la parte superior de mis encabezados en algún lugar: el uso de impulso :: asio :: :: ip tcp;

     

Digamos que hay un impulso :: :: asio ip :: :: TCP función de la barra

Dan Saks explica algunas razones por las que debe typedef nombres de las clases, a pesar de que podría parecer redundante.

Bueno, le han acabado en situaciones de la vida real, donde typedefing una clase tendría probablemente ayudó a encontrar su problema un poco más fácil:

 class bar {
 // ...
 };
 typedef class bar bar;

genera este mensaje más significativo si hay una función llamada bar() ya declaradas:

In file included from C:\temp\foo.h:4,
                 from C:\temp\test.cpp:4:
C:\temp\bar.h:7: error: `typedef class bar bar' redeclared as different kind of symbol
C:\temp\test.cpp:1: error: previous declaration of `void bar(int)'
C:\temp\bar.h:7: error: declaration of `typedef class bar bar'

Otros consejos

cheque todo lo doble. Si se incluye en bar.h foo.h, el compilador no debe levantar un error. ¿Se incluye INCLUDED_BAR_H de BAR_H_? Mejor no hacer esto porque eso causaría una dependencia circular entre cabeceras, lo que hará que ese tipo de errores.

También puedes ver la ortografía de los guardias de cabecera. Esto puede ser una fuente común de molestia:

#ifdef _BAR_H_ // OOPS! we wanted #ifndef
#define _BAR_H_

class bar {

};

#endif // _BAR_H_

Además, se debe evitar poner el guión antes de que su nombre de cabecera guardia macro. Estos nombres están reservados para el compilador. Llamarlo <=> o simplemente <=> lugar.

Tommy Hui y litb Ya ha apuntado a dos causas probables; he aquí algo de información que se espera será muy útil.

En primer lugar, esto no tiene nada que ver con los archivos make. Un makefile es sólo una cosa que llama la conveniencia g ++ para usted, nada más.

Esta cosa con los archivos de cabecera puede ser un poco difícil de entender al principio, especialmente una vez llegue a dependencias circulares. Realmente me ayudó a darse cuenta de estas tres cosas:

  • Una #include no es más que una operación de copiar / pegar, insertar el contenido del archivo incluido en ese punto.
  • Todo debe haber sido declarada antes de su uso. Algunas veces, cuando surgen dependencias circulares, puede que tenga que predeclarar una clase (por ejemplo class bar;) en otro remate de cabeza.
  • Si, en el momento de su empleo, se necesita más información acerca del tipo que sólo su existencia, entonces el tipo de definición se necesita también. Esto va para, por ejemplo, llamando de un método en un objeto de ese tipo, sino también para la inclusión de un campo de ese tipo! (No para un puntero a un objeto de ese tipo, sin embargo, porque los punteros son todos del mismo tamaño.)

En el main.cpp, tendrá que añadir la siguiente línea en la parte superior del archivo:

#include "foo.h"
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top