3 Stimmen

Wie man ein Programm in C++ aufteilt

Ich steige jetzt in OOP ein, aber die Dateien werden ziemlich groß. Ich habe mich gefragt, ob es möglich wäre, einige größere Funktionen in separate Dateien und die Klassen in eine separate Datei zu legen. Nehmen wir zum Beispiel an, ich habe den folgenden Code:

#include 
#include 
#include 

using namespace std;

//------------------------SHAPE------------------------------------//

class shape {
    protected:
        double area;
    public:
        shape(): area(0) {}
        shape(double A): area(A) {}
        virtual ~shape() {}
};

//------------------------SQUARE------------------------------------//

class square : public shape {

    friend ostream & operator<<(ostream &os, const square &squ);

    protected:
        double width;
    public:
        square(): shape(0), width(0) {}
        square(double w): shape(w*w), width(w) {}
        virtual ~square() {}

};

ostream & operator<<(ostream &os, const square &squ) {
    os << "Breite: " << squ.width << ", Fläche: " << squ.area;
    return os;
}

//------------------------CUBE-------------------------------------//

class cube : public square {

    friend ostream & operator<<(ostream &os, const cube &cub);

    public:
        cube(): square(0) {}
        cube(double w):
            square(w) {}
        cube(square squ):
            square(squ.getwidth()) {}
        ~cube() {}
        double volume() const {
            double temp = width*area;
            return temp;
        }

};
ostream & operator<<(ostream &os, const cube &cub) {
    os << "Breite: " << cub.width << ", Volumen: " << cub.volume();
    return os;
}

double square(double N) {
    return N*N;
}
//------------------------MAIN------------------------------------//

int main() {

    square s1;
    // andere Dinge

}

Wie würde ich die Klassen in eine Datei und die Funktion in eine andere Datei und das Hauptprogramm in eine weitere Datei legen, aber dennoch alles mit g++ kompilieren?

4voto

OnlineCop Punkte 3909

Typischerweise werden Ihre Deklarationen in einer .h-Datei platziert, und die Definitionen werden in mehrere .cpp-Dateien geschrieben.

Jede Datei, die die Struktur jeder dieser Klassen kennen muss, muss die .h-Datei mit #include einbinden.

Da Ihre shape-Klasse bereits gut strukturiert ist, kann sie praktisch unverändert in shape.h platziert werden.

Ihre square-Klasse, da sie von shape abgeleitet ist, muss neben einigen anderen globalen Includes wie #include auch #include "shape.h" einbinden, da sie ostream nutzt.

Ihre cube-Klasse mischt tatsächlich sowohl Deklaration ALS AUCH Definition in einigen Teilen, was besser aufgeteilt werden sollte: double volume() const sollte nur in der Datei cube.h deklariert werden und dann tatsächlich in cube.cpp mit folgendem Code definiert werden:

double cube::volume() const {
    double temp = width*area;
    return temp;
}

Wenn Sie tatsächlich kompilieren, erfolgt dies typischerweise, indem Sie sie in Objektdateien kompilieren, normalerweise auf der Befehlszeile mit g++ -c -o cube.o cube.cpp cube.h shape.h, wo eine Reihe von .o Dateien erstellt wird.

Nachdem alle diese einzelnen Dateien in diese .o Segmente kompiliert wurden, werden sie alle zusammengeführt und miteinander verknüpft: g++ -o my_completed_project shape.o square.o cube.o.

(Es könnte ein paar Tippfehler darin geben: Das alles war aus dem Kopf... Entschuldigung dafür.)

Insgesamt sieht Ihr Code für mich sehr sauber aus. Er ist gut strukturiert und leicht lesbar. Großartige Arbeit!

Bearbeiten:

Typischerweise gibt eine Deklaration nur die Struktur der Funktion an, sodass der Compiler weiß, dass sie einen bestimmten Rückgabetyp, den Namen der Funktion und den Typ und die Anzahl der Argumente hat. Der Compiler weiß nicht, was diese bestimmte Funktion tut; er will nur wissen, dass Sie das übergeben, was er erwartet, und dass Sie einen bestimmten Rückgabetyp erwarten.

Deklarationen gehören in die .h-Dateien und sind sehr minimalistisch: Sie geben nur an "wie die Funktion aussieht".

Definitionen hingegen gehören in die .cpp-Dateien, und beim Kompilieren des Programms sagt es dem Programm was zu tun ist, wenn diese Funktion aufgerufen wird. Die Datei cube.cpp definiert nun, was die volume()-Funktion tun soll (sie sollte width*area zurückgeben).

Da cube jedoch von der square-Klasse abgeleitet ist, interessiert sich der Compiler während der Kompilierzeit nur dafür, dass eine getwidth()-Funktion in square definiert ist, dass sie keine Parameter akzeptiert und dass sie ein double zurückgibt. Es ist ihm egal, wie er den Wert für dieses double erhält: nur die Tatsache, dass es in der square.h deklariert ist, reicht dem Compiler aus, um alle Informationen zu haben, die er zum Kompilieren von cube.h und cube.cpp benötigt.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X