C++-manual | ||
---|---|---|
Förutgående | Kapitel 13. Kompilera C++-program | Nästa |
De flesta progam når förr eller senare en kritisk storlek då det inte längre är överskådligt att placera all kod i en och samma fil. Var denna gräns kommer är beroende på programmeraren, men endel personer tycker om att ha många relativt små filer, medan andra föredrar större men färre filer. I C++ finns det förstås möjligheter till detta.
Då man har flera filer som skall i sista hand bli ett och samma program bör de enskilda filerna kompileras skilt för sig till s.k. objektfiler, som innehåller koden i assemblerform. När alla filer kompilerats till objektfiler länkas de alla ihop tillsammans med nödvändiga bibliotek och ett körbart program skapas. Exemplet nedan visar schematiskt hur ett program bestående av filerna a.cpp, b.cpp och c.cpp för kompileras till mostavarande objektfiler (.o) och sedan linkas till ett körbart program.
Figur 13-2. Kompilatorns arbetsskeden vid multipla filer
För att åstadkomma detta måste man se till att kompilatorn inte direkt försöker länka en fil som kompileras, utan denna skall "lämnas" i objektformatet. Man använder då flaggan -c. Man bör då inte ge med flaggor som har att göra med t.ex. bibliotek (-L och -l) men nog flaggor som har att göra med t.ex. var headerfiler finns. När alla filer kompierats är det dags att länka ihop dem till ett enda exekverbart program. Då ger man alla objektfiler på kommandoraden till kompilatorn och inkluderar eventuella länkningsflaggor, varvid kompilatorn skapar programmet (förutsatt att alllt är korrekt). Ovanstående program kunde kompileras på följande sätt:
% g++ -c a.cpp % g++ -c b.cpp % g++ -c c.cpp % ls a.cpp a.o b.cpp b.o c.cpp c.o % g++ a.o b.o c.o -o MittProgram % |
Som ett exempel på hur man kan använda separat kompilering och headerfiler i ett eget projekt skall vi titta på ett exempelprogram som definierar en enkelt stack (se avsnittet Allokering av sammansatta datatyper i Kapitel 12). Denna stack är simpel och innehåller endast några få funktioner. Vi skall separera implementationen av stacken i en skild fil Stack.cpp och definitionen av funktionsprototyper för stacken i Stack.h. Sedan skapar vi ett enkelt huvudprogram i en tredje fil StackMain.cpp som använder sig av vår stack.
Definitionsfilen Stack.h ser t.ex. ut på följande sätt:
// Stack.h // se till att vi inte får problem om filen inkluderas multipla gånger #ifndef STACK_H #define STACK_H // inkludera headers som kan behövas #include <iostream> // definiera ett element i stacken struct Element { // data för detta element char Data; // nästa element under detta i stacken Element * Previous; }; // funktionsprototyper Element * push (Element * Top); Element * pop (Element * Top, char & Data); bool isEmpty (Element * Top); #endif |
Filen Stack.cpp som innehåller den egentliga koden för alla funktioner ser ut som nedan. Den måste även inkludera Stack.h för att Element skall vara definierad.
// Stack.cpp -- implementation av stacken // inkludera våra egna definitioner #include "Stack.h" Element * push (Element * Top) { char Data; cout << "Elementets värde: "; cin >> Data; // skapa nytt element Element * New = new Element; New->Data = Data; New->Previous = Top; // återvänd och returnera nya topp-elementet return New; } // pop:a ett element från stacken Element * pop (Element * Top, char & Data) { // är stacken tom? if ( Top == 0 ) { // stacken tom return 0; } // spara data som är lagret i elementet Data = Top->Data; // spara pekare till det element som blir nytt topp-element Element * Tmp = Top->Previous; // frigör minne och återvänd delete Top; return Tmp; } // kolla om stacken är tom bool isEmpty (Element * Top) { if ( Top == 0 ) { // stacken tom return true; } // stacken inte tom return false; } |
Själva huvudprogrammet som använder sig av vår stack ser ut som nedan. Den enda skillnaden mellan detta program och det i avsnittet Allokering av sammansatta datatyper i Kapitel 12 är att nu finns hela stacken definierad och implementerad i andra filer, och det enda som behövs är en #include "Stack.h".
#include "Stack.h" int main () { Element * Top = 0; char Choice = ' '; char Data; // iterera tills användaren vill avsluta while ( Choice != '3' ) { cout << "Välj: " << endl << "1 - push" << endl << "2 - pop" << endl; cout << "3 - sluta " << endl << "-> "; // läs in ett menyval cin >> Choice; // vad vill användaren göra switch ( Choice ) { case '1' : Top = push ( Top ); break; case '2' : // har vi element i listan? if ( ! isEmpty ( Top ) ) { // ja, poppa och skriv ut det poppade värdet Top = pop ( Top, Data ); cout << "Poppade: " << Data << endl; } else { cout << "Stacken tom!" << endl; } break; } } } |
Programmet kan sedan kompileras med följande kommandon:
% g++ -c Stack.cpp % g++ StackMain.cpp Stack.o % ./Stack ... |
Notera att vi här kompilerade och länkade StackMain.cpp på samma gång genom att räkna upp de objekt-filer vi ville länka med på kommandoraden. Vi kunde även kompilerat även denna fil men flaggan -c och sedan gjort en separat länkning av programmet.
Förutgående | Hem | Nästa |
Länkning av program | Upp | Klasser |