Gå til innhold

#include problem mellom to filer


Anbefalte innlegg

Jeg koder et spill i Dev-C++, og har et problem jeg har klart å isolere til noe sånt:

 

Jeg har en database med et STL-map 'shiplist' hvor keyen er filnavnet til skipet, og dataen er et Ship-objekt. Databasen laster inn filer fra harddisken sånn at resten av programmet kan laste nye skip fra databasen istedenfor ifra harddisken hele tiden.

 

Ship-klassen har en konstruktør som tar et filnavn og en referanse til et Database-objekt, og spør databasen om en kopi av skipet med filnavnet.

 

Koden:

 

Jeg har en fil ship.h:

#ifndef SHIP_H
#define SHIP_H

#include <string>
#include "database.h"

class Ship
{
  public:
     Ship(std::string shipfile, Database &database) 
        { this = database.Getship(shipfile); }

  private:
};

#endif

og en fil database.h:

#ifndef DATABASE_H
#define DATABASE_H

#include <map>
#include <string>
#include "ship.h"

class Database
{
  public:
     Ship Getship(std::string shipfile)
        { return shiplist[shipfile]; }

  private:
     std::map<std::string, Ship> shiplist;

};

#endif

 

Hvis jeg inkluderer begge headerfilene i f.eks main.cpp, så får jeg masse feilmeldinger som ser ut som hele koden er skrevet feil... Jeg antar problemet ligger i at Ship inkluderer Database som igjen inkluderer Ship osv men skjønner ikke akkurat hva problemet er eller hvordan en kan løse det.

Endret av aspa
Lenke til kommentar
Videoannonse
Annonse

Fjern definisjonene fra headerfilene og bruk forward reference.

 

main.cpp:

#include <iostream>
#include "database.h"
#include "ship.h"

using namespace std;


int main() 
{
Database db;
Ship ship("Fri", db);
return(0);
} // main()

 

database.h:

#ifndef DATABASE_H
#define DATABASE_H

#include <map>
#include <string>


class Ship; // Forward reference


class Database {
public:
Ship getShip(std::string shipfile);	


private:
std::map<std::string, Ship> shiplist;
}; // class Database


#endif // #define DATABASE_H

 

ship.h:

#ifndef SHIP_H
#define SHIP_H

#include <string>
#include "database.h"


class Ship {
public:
Ship(std::string filename, Database& db);
}; // class Ship


#endif // #define SHIP_H

 

Når du linker dette klager seff. linkeren på at den ikke finner noe definisjoner av konstruktøren til Ship og senere Database::getShip, disse legger du i ship.cpp og database.cpp og kompilerer:

 

g++ -c ship.cpp database.cpp main.cpp

 

..før du linker sammen:

 

g++ ship.o database.o main.o -o main.exe

 

 

Edit:

Husk at du må bruke peker-til-ship hvis du skal ha virtuelle metoder i Ship-klassen og sub-typer av (den abstrakte?) Ship. "Polyformi" .. eller hva-det-nu kalles.

 

Beklager at jeg endret litt på kodestilen .. men jeg gjør det automatisk. :}

Endret av søppel
Lenke til kommentar

Forward declaration (evt. class declaration) er vel det egentlige navnet. Det betyr kort sagt:

 

"Det ER en klasse som heter dette, heelt sant! Så skal jeg fortelle mer om den senere..."

 

Edit: Så litt nøyere på det hele. Et par kommentarer...

 

Du kan kompilere og linke i ett med g++ -o main.exe main.cpp ship.cpp database.cpp, du ikke gjøre det i to steg.

 

Anbefaler dessuten å bare bruke en klassedeklarasjon, med mindre det er absolutt nødvendig å ha med hele klassedefinisjonen. Det er ikke nødvendig å ha med klassedefinisjonen (som ofte blir tatt med via #include) når du bare deklarerer medlemsfunksjoner som på en eller annen måte bruker den klassen (altså, den du deklarerer / #include'er).

 

Du kan kanskje ta en titt på en bruker-guide jeg har skrevet (pluss kildene jeg refererer til), som er noe relevant til dette.

 

Tilleggsnotater:

Han har definert funksjonene. Inline, vel å merke, men de er like fullt definert.

Det heter polymorphism, som direkte oversatt blir "mangeformhet" ("polyform" var dermed ikke så langt unna ;)

Endret av Myubi
Lenke til kommentar

Forward reference og det at du ikke definerer funksjonene (metodene) er det som skulle til. :]

 

Du kan kompilere og linke i ett med g++ -o main.exe main.cpp ship.cpp database.cpp, du må ikke gjøre det i to steg.

 

Riktig det. Grunnen til at jeg viste det slik er at det da blir lettere når man siden skal rote med Makefiles og stuff. Altså når man vet åssen dette med å kompilere først og så linke, fungerer.

Endret av søppel
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...