[gelöst] C++ programmieren unter Anjuta (Debian 6)



  • Hi elise,

    elise schrieb:

    und: warum nicht auch mal den fußweg nutzen? über konsole... ohne ide? du sagtest ja: du wollest c++ richtig kompilieren lernen 😉

    ok ok, die meisten empfinden das als zu anstrengend, ohne "knopfdruck".
    trotzdem: hänge dein herz nicht an ides. auch wenn sie das leben erleichtern.

    So meinte ich das nicht, ich bin gerne bereit es richtig tm über die Konsole zu lernen [1].

    Ich finde z.B. die Erklärung mittels Autotools sehr gut und ich habe das über die Konsole auch nachgebaut, funktioniert wunderbar.

    Darauf aufbauend ergeben sich für mich sofort drei Fragen:
    i) Wie muss ich die obige Anleitung modifizieren, wenn ich unter C++ programmieren möchte?
    ii) Das ganze scheint jetzt nur für eine Datei zu sein, also Sourcecode in Datei stecken und kompilieren wollen?
    iii) Jetzt möchte ich für einen größeren Code natürlich diverse Elemente in header-Dateien auslagern, wie binde ich erfolgreich ein? Ist das dann ein Projekt?

    Wie gesagt, gerne alles in der Konsole, bin motiviert es richtig tm zu lernen. 🙂

    Viele Grüße,
    Klaus.

    [1] Wobei ich denke der gewitzte Linux User schreibt sich dann ein Miniskript und macht es mit der Kombination 'arrow-up' + Enter auch fast wieder zum Knopfdruck! 😉



  • c++ nutzt als compiler g++. (schau mal in deinen makefile rein)
    hier einer von vielen links dazu, den ersten gegriffen:
    http://webusers.npl.illinois.edu/~yangrz/Make.html



  • du sagst, du kannst bisher schleifen, zeiger, referenzen, dateiarbeit... klingt vorerst nach c, bis auf die referencen.

    wie sieht es aus mit c++?
    klassen,instanzen, new, delete, operatoren überladen, methoden überladen, streams, kopierkonstruktor, überladen des zuweisungsoperators, polymorphie... virtuelle methoden, u.v.m.

    die beschäftigung mit autotools und ides mag interessant sein. sollte dich aber nicht abhalten, weiter c++ zu lernen 😉 (und ich weiß, wovon ich rede *g)



  • Hi,

    elise schrieb:

    wie sieht es aus mit c++?
    klassen,instanzen, new, delete, operatoren überladen, methoden überladen, streams, kopierkonstruktor, überladen des zuweisungsoperators, polymorphie... virtuelle methoden, u.v.m.

    Also Klassen verwende ich und auch new und delte. Operatoren überladen: Zählt es den Konstruktor einer Klasse zu überladen? Methoden überladen habe ich glaube ich auch schon.
    Bei streams habe ich bisher fstream verwendet, um in Dateien zu schreiben oder von ihnen zu lesen.

    Ich meine, ich weiß nicht inwieweit hier in der Physik richtiges tm programmieren nötig ist. Bisher ist es eher eine Mischung aus Programmieren und Numerik, um Formeln in die Maschine zu kloppen oder Integrale lösen zu lassen, wo die Analytik versagt.

    So habe ich i.d.R. drei Fronten zwischen der Physik, der Numerik und schließlich dem Programmieren. Wobei ich das Programmieren selbst nicht unbedingt vernachlässigen möchte, denn ich denke je besser ich darin werde, um so effizienter werden meiner Programme und damit schneller.

    Ich arbeite mit der Monte Carlo Methode,d.h. ich muss über viele Durchgänge mitteln, und jeder Geschwindigkeitszuwachs bedeutet mehr Durchläufe in der gleichen Zeit, sodass die anschließende Mittelung eine bessere Statistik liefert. 🙂

    Gruß,
    Klaus.



  • Die Autotools würde ich erstmal außen vor lassen. Die mögen ja sehr beliebt bei GNU und Konsorten sein, aber du lernst dadurch nicht viel besser, wie deine IDE unter der Haube funktioniert.



  • Klaus82 schrieb:

    Mein Problem ist, dass ich weder in der Schule noch an der Uni Informatik gehört hatte. Es hat sich bei meiner Arbeit aber ergeben, dass ich Programmieren muss. Nicht schlimm, die Herausforderung nehme ich an.

    Da frage ich mich was das für eine Firma ist, die Mitarbeiter für Aufgaben anstellt, für die sie gar nicht qualifiziert sind und dann auch noch erwartet, daß diese Mitarbeiter diese Aufgaben lösen können?

    Wieso stellt die Firma in der du arbeitest nicht einfach entsprechende Fachkräfte ein?

    Was soll das jetzt mit deiner Erwartung, daß du mal so auf die schnelle C++ lernen und später Software entwickeln könntest?

    Nur mal so zur Info.
    Um C++ einigermaßen gut zu können, braucht man etwa 10 Jahre Erfahrung und Übung.
    Um dann anschließend komplette Software zu entwickeln, braucht man dann noch mal deutlich mehr Hintergrundwissen.
    Mit dem reinen lernen einer Programmiersprache ist es also nicht getan.

    Ein Informatikstudium dauert nicht ohne Grund 3-5 Jahre.

    Das ganze ist für mich nun aber ein zweischneidiges Schwert. Zum Einen muss ich natürlich vorwärts kommen, dass ich auch Ergebnisse liefere und mein Chef sich nicht fragt, für was sie mich eigentlich bezahlt.

    Du wirst scheitern.
    C++ lernst du nicht in 10 Tagen.

    Vielleicht kriegst du mit viel Glück ein undefiniertes etwas zusammen, das irgendwie tut, mit Klebeband und Bindfäden zusammengeflickt ist, aber ordentliche Software wird das nicht sein.
    Dein Chef muß unqualifiziert genug sein, damit er dir so ein Machwerk dann abnimmt.
    Wenn dein Chef auch so ein Auto bauen würde, dann gute Nacht.

    Zum Anderen, möchte ich natürlich aber auch rückwärts arbeiten (für was man i.d.R. weniger bezahlt wird), d.h. ich würde gerne genauer verstehen was ich da tue.

    Dann besorg dir entsprechende Literatur.
    C++ lernst du nicht, in dem du hier solche Fragen stellst.

    Ich habe jetzt das Problem, dass ich ein wenig Heimarbeit einrichten möchte und habe meinen PC mit Debian 6 aufgesetzt. Im Büro verwende ich zwar Netbeans als IDE, doch hier zu Hause habe ich mir jetzt mal Anjuta angesehen, weil ich beim Stöbern auf der Debian Homepage den Eindruck habe, dass es schlanker ist, weil nur für C++ zuständig?

    Oh je ne me, selbst da fehlt das Rüstzeug.

    Tue dir selbst einen Gefallen, laß es und sag deinem Chef er soll die Arbeit an eine Person weiterreichen, die dafür auch qualifiziert ist.

    Kann mir jemand helfen, wie ich am Besten Land sehe? 😞

    Gruß,
    Klaus.

    Befolge das was ich hier oben geschrieben habe.

    Und Anjuta ist meiner Meinung nach nicht die Beste IDE für C++, auch nicht unter Linux.



  • Okay,

    und nach dieser herben aber konstruktiven Kritik wieder weiter im Programm. 🙂

    Mein bisheriger Wunsch war einen Sourcecode zu kompilieren ohne ein Projekt anlegen zu müssen.

    Da bin ich z.B. hier fündig geworden. Ich habe also mittels gedit einen einfachen Code geschrieben und in der Konsole mittels

    g++ -Wall -pedantic -ansi -o ionization ionization.cpp
    

    das ganze kompiliert.

    Anschließend kann ich dann das Programm in der Konsole mittels

    ./ionization
    

    ausführen.

    Klappt alles wunderbar! 🙂

    Jetzt frage ich mich natürlich, was im Unterschied dazu ein ganzes Projekt sein soll, wie es weiter oben oder eben hier mit Autotools beschrieben wird.
    Wozu der Umstand über die Reihenfolge

    ./configure > make > make install
    

    Ich schätze mal, dass dieser zweite Weg den ersten enthält. Denn wenn ich die configure Datei aufrufe, so wird ja irgendwie ein Kompiler gcc aktiviert.
    Also wird das ganze kompiliert, was ich manuell oben über die Eingabe mittels

    g++ -Wall -pedantic -ansi -o ionization ionization.cpp
    

    mache, oder nicht?

    Diese Sache mit make und make install sorgt dann nur dafür, dass ich die Datei von jedem Verzeichnis aus aufrufen kann.

    Doch wozu das alles? Ich meine dieser zweite Weg fängt ja gleich an ganze Verzeichnisse anzulegen und nennt sich sicherlich nicht umsonst 'building project'.

    Gruß,
    Klaus.





  • Hi Ohjemene,

    Ohjemene schrieb:

    Nimm Geany:
    http://www.geany.org/

    Und warum?

    Du hattest dich vorher gegen Anjuta ausgesprochen

    Ohjemene schrieb:

    Und Anjuta ist meiner Meinung nach nicht die Beste IDE für C++, auch nicht unter Linux.

    Doch warum jetzt für Geany?

    Gruß,
    Klaus.



  • Doch wozu das alles?

    Naja, bei einer Datei ohne externe Abhängigkeiten scheint das natürlich unnötig kompliziert. Aber die meisten Projekte bestehen aus sehr viel Code und den teilt man dann sinnvollerweise in mehrere Dateien auf und man benutzt in den meisten Fällen auch externe Abhängigkeiten. ./configure sorgt nun dafür, dass die ganzen externen Abhängigkeiten überprüft und aufgelöst werden. make sorgt dafür, dass das ganze Projekte (also jede Datei und nur wenn Änderungen vorliegen) gebaut wird und make install installiert das ganze. Das Konzept ist also schon sinnvoll.



  • Hm,
    verstehe. Na ja, die Frage ist wahrscheinlich, ob ich im Alleingang so komplexe Codes baue.
    Wenn ich mir jetzt allerdings meinen Code so ansehe. Ich bin schon versucht viele Definitionen von physikalischen Konstanten oder Funktionen in header Dateien auszulagern.

    Zumindest dachte ich, dass das auch in die Richtung der Idee des Objekt orientierten Programmierens geht. Man bastelt ein 'Objekt', definiert den In- und Output und behandelt es dann als Blackbox. Somit kann man die Programmierung von solch einzelnen Teilen weitergeben, muss es anschließend nur einbinden und kann es aufrufen.
    Und es hat den Vorteil, dass ich bei Änderungen nur in den Objekten selbst was ändern muss und nicht meinen endlosen langen Quellcode durchsuchen muss.

    Wie gesagt, bisher habe ich viele Programmteile auch ausgelagert:

    #include<iostream>
    #include<cmath>
    #include<fstream>
    // Numerical Recipes
    #include</home/klaus/NumericalRecipes/code/nr3.h>
    #include</home/klaus/NumericalRecipes/code/ran.h>
    #include</home/klaus/NumericalRecipes/code/roots.h>
    // personal header files
    #include</home/klaus/Water/HeaderFiles/F1.h>
    #include</home/klaus/Water/HeaderFiles/F2.h>
    #include</home/klaus/Water/HeaderFiles/physicalConstants.h>
    #include</home/klaus/Water/HeaderFiles/alpha.h>
    #include</home/klaus/Water/HeaderFiles/beta.h>
    #include</home/klaus/Water/HeaderFiles/gamma.h>
    #include</home/klaus/Water/HeaderFiles/delta.h>
    #include</home/klaus/Water/HeaderFiles/totalIonizationCrossSection.h>
    #include</home/klaus/Water/HeaderFiles/diffIonizationCrossSection.h>
    #include</home/klaus/Water/HeaderFiles/totalElasticScatteringCrossSection.h>
    #include</home/klaus/Water/HeaderFiles/diffElasticScatteringCrossSection.h>
    

    Nur leider habe ich feststellen müssen, dass die header Dateien eben in der richtigen Reihenfolge stehen müssen.
    Z.B. verwendet die header Datei totalElasticScatteringCrossSection.h Elemente aus apha.h, beta.h, gamma.h. und delta.h.
    Aus diesem Grund müssen die weiter vorne stehen.

    Aber ich 'erstelle' alles per Knopfdruck mit der einfachen Kommandozeile

    g++ -Wall -pedantic -ansi -o "%e" "%f"
    

    Also nichts mit

    ./configure > make > make install
    

    Oder läuft das beim Erstellen im Hintergrund ohne, dass ich es mitbekomme?

    Gruß,
    Klaus.



  • Klaus82 schrieb:

    Aber ich 'erstelle' alles per Knopfdruck mit der einfachen Kommandozeile

    g++ -Wall -pedantic -ansi -o "%e" "%f"
    

    Also nichts mit

    ./configure > make > make install
    

    Oder läuft das beim Erstellen im Hintergrund ohne, dass ich es mitbekomme?

    Gruß,
    Klaus.

    na schau dir einfach mal den dazugehörigen makefile im editor an 😉

    kann falsch sein, aber irgendwie glaub ich, du hast das erstellen noch nicht durchdacht. schau dir dazu folgende begriffe an: präprozessor, compiler, linker. in dieser reihenfolge.



  • Klaus82 schrieb:

    Hm,
    verstehe. Na ja, die Frage ist wahrscheinlich, ob ich im Alleingang so komplexe Codes baue.

    Hat nix mit komplex zu tun. Wenn du objektorientiert C++ programmierst, hast du normalerweise pro Klasse einen Header und ein Sourcefile, dann noch ein Sourcefile für die main. Schon bei den einfachsten Projekten musst du dich also mit getrennter Compilierung und darauffolgendem Linken auseinandersetzen.

    Nur leider habe ich feststellen müssen, dass die header Dateien eben in der richtigen Reihenfolge stehen müssen.
    Z.B. verwendet die header Datei totalElasticScatteringCrossSection.h Elemente aus apha.h, beta.h, gamma.h. und delta.h.
    Aus diesem Grund müssen die weiter vorne stehen.

    Nee, totalElasticScatteringCrossSection.h sollte alles inkludieren, was es braucht.

    Aber ich 'erstelle' alles per Knopfdruck mit der einfachen Kommandozeile

    g++ -Wall -pedantic -ansi -o "%e" "%f"
    

    %e %f? Sagt mir leider nichts.



  • Bashar schrieb:

    Klaus82 schrieb:

    Hm,
    verstehe. Na ja, die Frage ist wahrscheinlich, ob ich im Alleingang so komplexe Codes baue.

    Wenn du objektorientiert C++ programmierst, hast du normalerweise pro Klasse einen Header und ein Sourcefile, dann noch ein Sourcefile für die main.

    Okay,
    ist immer viel auf einmal an Infos und dann reden wir noch nicht über guten Programmierstil.

    Wenn ich das soweit richtig verstanden habe, dann beginne ich in einer header Datei zunächst mit der sogenannten Deklaration, d.h. ich führe zunächst eine Größe wie eine Funktion erstmal ein.

    // header.h
    double function (double x);
    

    In der c oder cpp Datei binde ich die Header Datei zunächst ein und fülle die deklarierten Elemente mit Leben.

    // function.cpp
    #include<header.h>
    double function (double x){ return x*x; }
    

    Und anschließend muss natürlich jede Datei in meine Hauptdatei, wo alle Fäden zusammenführen.

    // main.cpp
    #include<function.cpp>
    // ... Hauptteil
    

    Kann man das so sehen?

    Bashar schrieb:

    Aber ich 'erstelle' alles per Knopfdruck mit der einfachen Kommandozeile

    g++ -Wall -pedantic -ansi -o "%e" "%f"
    

    %e %f? Sagt mir leider nichts.

    Entschuldige, das ist der Syntax von Geany für die Kommandozeile zum Erstellen.
    Dabei steht wohl "%e" als Platzhalter für den Dateiname später, wobei die Endung c oder cpp gerade weggelassen wurde, während "%f" die zu kompilierende Datei ist.

    Viele Grüße,
    Klaus.



  • Klaus82 schrieb:

    Wenn ich das soweit richtig verstanden habe, dann beginne ich in einer header Datei zunächst mit der sogenannten Deklaration, d.h. ich führe zunächst eine Größe wie eine Funktion erstmal ein.

    // header.h
    double function (double x);
    

    So kann man das sehen, allerdings stellt sich da ja automatisch die Frage nach dem Warum. Es ist eher so: Du möchtest die Funktion in einem Sourcefile definieren und in einem anderen aufrufen, also muss sie nach außen bekannt gemacht werden. Dazu schreibst du eine Deklaration.

    In der c oder cpp Datei binde ich die Header Datei zunächst ein und fülle die deklarierten Elemente mit Leben.

    // function.cpp
    #include<header.h>
    double function (double x){ return x*x; }
    

    Ja. Außer dass man beim Include von eigenen "header.h" schreibt. Die <...>-Syntax ist für Header der Standardlibrary u.ä. gedacht. Der technische Unterschied liegt darin, ob und wie der Include-Pfad berücksichtigt wird.

    Und anschließend muss natürlich jede Datei in meine Hauptdatei, wo alle Fäden zusammenführen.

    // main.cpp
    #include<function.cpp>
    // ... Hauptteil
    

    Kann man das so sehen?

    Nein, du bindest normalerweise keine cpp-Dateien ein. (Wo lernt man sowas?) Du compilierst alle cpp-Dateien getrennt. Inkludieren tust du nur Headerdateien.

    Das läuft auf der Kommandozeile zu Fuß folgendermaßen. Zuerst getrennte Compilierung aller cpp-Dateien:

    g++ -Wall -ansi -c foo.cpp
    g++ -Wall -ansi -c bar.cpp
    ...
    

    Es entstehen lauter gleichnamige .o-Dateien. In einem zweiten Schritt werden die nun zusammengelinkt:

    g++ -o meinProgramm foo.o bar.o ...
    

    Das hat den Vorteil, dass man nur die Dateien neu compilieren (und dann wieder alles linken) muss, die sich geändert haben oder bei denen sich Änderungen aus eingebundenen Headerdateien auswirken. Ich arbeite hier z.B. an einem Projekt mit einigen Tausend Quelldateien, wenn ich da nach jeder Änderung erstmal eine halbe Stunde Pause machen könnte wäre das auch nur am Anfang nett.

    An der Stelle kommen Makefiles oder Projekte usw. ins Spiel, weil du normalerweise das nicht alles von Hand machen willst. Du willst ein Tool, das mehr oder weniger automatisch nur die Dateien compiliert, die compiliert werden müssen, und alles zusammenlinkt.



  • Ah,

    ich glaube langsam verstehe ich. 🙂

    Ich habe leider keine Ausbildung in Richtung Informatik genossen, weder in der Schule noch während des Physik Studiums als Nebenfach o.ä. Das rächt sich jetzt ein wenig.

    Ich hatte kurz vor dem Diplom ein wenig Labview programmiert [1] und damit erstmals auch generell programmiert [2].

    Jetzt bin ich aus der Experimental- in die theoretische Physik übergewechselt, d.h. Mathematik, Numerik und Programmieren als Werkzeug, wenn man so möchte.

    Und da ich gerne mehr verstehe als Knöpfchen drücken im Sinne von "jetzt spuckt er mir das Ergebnis der Formel aus, die ich reingekloppt habe" bin ich jetzt vermehrt an C++ selbst interessiert samt dem was dazugehört wie Compiler (und Linker, usw.)

    Natürlich werde ich nie das Verständnis eines Informatikers erreichen, doch würde ich gerne so viel verstanden haben wie möglich.
    Und da ich jetzt von Windows auf Linux umgestiegen bin, zwinge ich mich durch die Eingabe mittels Konsole immer mehr verstehen zu müssen.

    Natürlich kann ich es mir irgendwann einfach machen, indem ich mir eine Makefile bastle (oder ein shell skript?), aber dann weiß ich wenigstens was die Einträge bedeuten.

    Gruß,
    Klaus.

    [1] Falls das für Puritaner programmieren ist. 😉
    [2] Okay, bis auf den BASIC programmierbaren Taschenrechner meines Vaters, dem ich dann zu Schulzeiten die abc Formel einprogrammiert habe.



  • Bashar schrieb:

    Nein, du bindest normalerweise keine cpp-Dateien ein. (Wo lernt man sowas?) Du compilierst alle cpp-Dateien getrennt. Inkludieren tust du nur Headerdateien.

    Wobei ich in diesem Kontext gleich noch eine Frage nachschieben möchte:

    Ich habe in einem anderen Thread geschrieben, dass ich jetzt versuche mit der GSL zu arbeiten [1].

    Wenn man nun aber einen Blick in das Handbuch, genauer auf das Beispiel wirft, so sieht man, dass dort in eine Datei sowohl header- als auch c-Dateien includiert werden:

    #include <stdio.h>
         #include <gsl/gsl_errno.h>
         #include <gsl/gsl_math.h>
         #include <gsl/gsl_roots.h>
    
         #include "demo_fn.h"
         #include "demo_fn.c"
    
         int
         main (void)
         {
           int status;
           int iter = 0, max_iter = 100;
           const gsl_root_fsolver_type *T;
           gsl_root_fsolver *s;
           double r = 0, r_expected = sqrt (5.0);
           double x_lo = 0.0, x_hi = 5.0;
           gsl_function F;
           struct quadratic_params params = {1.0, 0.0, -5.0};
    
    // und so weiter
    

    Wie ist das zu verstehen?

    Gruß,
    Klaus.

    [1] Daraus ist ja auch erst die Problematik mit dem Compiler und Linker entstanden.



  • Klaus82 schrieb:

    Hi Ohjemene,

    Ohjemene schrieb:

    Nimm Geany:
    http://www.geany.org/

    Und warum?

    Du hattest dich vorher gegen Anjuta ausgesprochen

    Doch warum jetzt für Geany?

    Weil Geany ein zum Progammieren guter Editor ist, deutlich besser als Gedit.
    Anjuta ist eine IDE, eine IDE mit einem Editor zu vergleichen ist wie Apfel und Birnen.

    Und ich halte es für den Anfang nicht für falsch, erstmal nur einen Editor zu benutzen. Wenn man dies tut, dann sollte man allerdings einen guten Editor nehmen. Geany ist so einer.

    Wie gesagt, bisher habe ich viele Programmteile auch ausgelagert:

    #include<iostream>
    #include<cmath>
    #include<fstream>
    // Numerical Recipes
    #include</home/klaus/NumericalRecipes/code/nr3.h>
    #include</home/klaus/NumericalRecipes/code/ran.h>
    #include</home/klaus/NumericalRecipes/code/roots.h>
    // personal header files
    #include</home/klaus/Water/HeaderFiles/F1.h>
    #include</home/klaus/Water/HeaderFiles/F2.h>
    #include</home/klaus/Water/HeaderFiles/physicalConstants.h>
    #include</home/klaus/Water/HeaderFiles/alpha.h>
    #include</home/klaus/Water/HeaderFiles/beta.h>
    

    Gewöhne dir ab, in deinem Quellcode absolute Pfade zu verwenden.
    Außerdem gehören eigene Headerdateien in Anführungszeichen gesetzt.
    Spitze Klammern sind nur für Headerdateien gedacht, die Systemweit z.B. unter /usr/include installiert sind.
    In der Regel benutzt man diese für Bibliotheken.

    Ich habe in einem anderen Thread geschrieben, dass ich jetzt versuche mit der GSL zu arbeiten [1].

    Bei weitergabe deines Programms mußt du dann auch den Quellcode unter die GPL stellen und mitliefern, ich hoffe du weißt das.
    Die GSL steht nämlich nicht unter der LGPL, sondern unter der GPL.



  • Alles klar,

    aber jetzt bitte nochmal zurück zu meiner Fragestellung.

    Ich verstehe das Argument von Bashar sehr gut, der da schreibt:

    Bashar schrieb:

    Nein, du bindest normalerweise keine cpp-Dateien ein. (Wo lernt man sowas?) Du compilierst alle cpp-Dateien getrennt. Inkludieren tust du nur Headerdateien.

    Das läuft auf der Kommandozeile zu Fuß folgendermaßen. Zuerst getrennte Compilierung aller cpp-Dateien:

    g++ -Wall -ansi -c foo.cpp
    g++ -Wall -ansi -c bar.cpp
    ...
    

    Es entstehen lauter gleichnamige .o-Dateien. In einem zweiten Schritt werden die nun zusammengelinkt:

    g++ -o meinProgramm foo.o bar.o ...
    

    Was mich jetzt nur ein wenig wundert ist die Fragestellung, dass die zuvor einzeln kompilierten Dateien doch durchaus miteinander verflochten sind. Also mit der obigen Bezeichnung kann es ja sein, dass ich etwas in foo.cpp kompiliere, was ich dann in bar.cpp verwende.

    Aus diesem Grund stelle ich mir gerade naiv vor, dass doch beim kompilieren von bar.cpp ein Fehler entstehen müsste.

    Natürlich macht es intuitiv Sinn, dass ich dann einen Linker aufrufe, der die Dateien anschließend verknüpft. Doch das findet ja nach dem kompilieren statt. Und so beißt sich für mich die Katze irgendwie in den Schwanz. 😕

    Ich kenne es bisher nur von LaTex, dass ich einzelne Kapitel bearbeite und so nicht immer das ganze Dokument kompilieren muss. Doch dann bleiben Querverweise erstmal leer oder werden mit einem ? gefüllt.
    D.h. ich kann Kapitel gar nicht einzeln kompilieren, wenn sie anschließend zu einem Gesamtdokument zusammengefügt werden sollen.

    Wie passt das denn zusammen?

    Gruß,
    Klaus.



  • Es gibt eben die "One Definition Rule". Du darfst für jedes Symbol (Variable, Funktion, Klasse, Struktur, etc.) nur eine Definition (also Implementierung haben) aber beliebig viele Deklarationen. Der Linker löst dann am Ende ohne Probleme die Symbole (LaTeX mäßig eben die ?? bei den Verweisen) auf.

    Bsp

    // foo.hpp
    #ifndef FOO_HPP
    #define FOO_HPP // Include guards um Mehrfacheinbindung zu verhindern
    
    extern void foo(); // Deklaration
    
    #endif
    
    // foo.cpp
    #include "foo.hpp" // Beachte: Keine absoluten Pfade! Niemals nie!
    #include <iostream>
    
    void foo() { // Definition
      std::cout << "Hello World\n";
    }
    
    #include "foo.hpp"
    
    int main() {
      foo(); // Der Compiler generiert hier sozusagen "??" und der Linker löst das auf in einen Aufruf von foo
    }
    

    g++ -Wall -Wextra -pedantic -ansi -c foo.cpp
    g++ -Wall -Wextra -pedantic -ansi -c main.cpp
    g++ foo.o main.o -o foo
    ./foo
    Hello World


Anmelden zum Antworten