Domanda

Buona sera:)

Sto giocando intorno con g ++ e makefile. Ho ottenuto a questo 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 è infine incluso nel mio file cpp principale in modo da poter impostare le cose in movimento chiamando start / stop.

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

Poi c'è bar.h:

#ifndef _BAR_H_
#define _BAR_H_

class bar {

};

#endif // _BAR_H_


g ++ non sembra piacere comunque:

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

sto usando makefile, e ha cercato una combinazione di cose come:

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

Anche se non credo che avrei dovuto aggiungere bar.h qui, non dovrebbe includendolo nel foo.h essere abbastanza?

Per chiarire, questo è più o meno come è impostato ora (sì, lo so questo può essere fatto in modo più efficiente):

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

Che cosa sta succedendo? Decido che è qualcosa che mi manca circa g ++ e il modo in cui gestisce intestazione include, mi punto nella giusta direzione per favore!

modifica - trovato la soluzione:

Doh! Mi sento stupida in questo momento. È stato nei guai con boost :: ASIO e tipo di dimenticato che ancora lasciato questo in cima alla mia intestazioni da qualche parte: utilizzando boost :: asio :: ip :: tcp;

Diciamo solo che c'è un boost :: asio :: ip :: tcp funzione :: bar: D

Oh bene, grazie comunque!

È stato utile?

Soluzione

  

È stato nei guai con boost :: ASIO e tipo di dimenticato che ancora lasciato questo in cima alla mia intestazioni da qualche parte: usare il boost :: asio :: ip :: tcp;

     

Diciamo solo che c'è un boost :: asio :: ip :: tcp :: funzione bar

Dan Saks spiega alcuni motivi per cui si dovrebbe typedef vostri nomi di classe, anche se potrebbe sembrare ridondante.

Bene, hai esegue in situazione di vita reale, dove typedefing una classe avrebbe probabilmente aiutato a trovare il vostro problema un po 'più facile:

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

genera questo messaggio più significativo se c'è una funzione denominata bar() già dichiarato:

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'

Altri suggerimenti

ricontrollare il tutto. Se si include bar.h in foo.h, il compilatore non dovrebbe suscitare un errore. Ti includere INCLUDED_BAR_H da BAR_H_? Meglio non fare questo perché sarebbe causare una dipendenza circolare tra le intestazioni, che farà sì che questo tipo di bug.

Anche controllare l'ortografia di guardie di intestazione. Questo può essere una fonte comune di fastidio:

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

class bar {

};

#endif // _BAR_H_

Inoltre, si dovrebbe evitare di mettere la sottolineatura prima intestazione nome guardia macro. Questi nomi sono riservati al compilatore. Chiamatela <=> o semplicemente <=> invece.

Tommy Hui e litb hanno già fatto a due cause probabili; ecco alcune informazioni di base che, si spera in utile.

Prima di tutto, questo non ha nulla a che fare con makefile. Un makefile è solo una cosa convenienza che richiede g ++ per voi, niente di più.

Questa roba con i file di intestazione può essere un po 'difficile da capire a prima, soprattutto una volta che si entra in dipendenze circolari. E 'davvero mi ha aiutato a realizzare queste tre cose:

  • Un #include non è altro che un'operazione di copia / incolla, inserendo il contenuto del file incluso in quel punto.
  • Ogni cosa deve essere stato ha dichiarato prima di essere utilizzato. A volte, quando le dipendenze circolari affiorano, potrebbe essere necessario predichiarare una classe (ad esempio class bar;) in un altro colpo di testa.
  • Se, nel punto di utilizzo, sono necessarie più informazioni sul tipo che solo la sua esistenza, quindi il tipo di definizione è necessario pure. Questo vale per esempio chiamando di un metodo su un oggetto di quel tipo, ma anche per l'inclusione di un campo di questo tipo! (Non per un puntatore ad un oggetto di questo tipo, però, perché i puntatori sono tutti della stessa dimensione.)

Nel main.cpp, è necessario aggiungere la seguente riga nella parte superiore del file:

#include "foo.h"
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top