Module/pakete programmieren
-
// Include-Guards zum Schutz vor Mehrfachinkludierung in ein und der selben // Übersetzungseinheit #ifndef MEIN_HEADER_H_INCLUDED #define MEIN_HEADER_H_INCLUDED class EineKlasse { // ... }; // andere Deklarationen bzw. Klassendefinitionen ... #endif
muss in des class ne klasse rein, muss die überhaupt da sein? ich würd gern mit funktionen arbeiten hab noch net soviel mit klassen gehabt, kann ich da einfach die voids reinstellen und dann per include die bibliothek einbinden?
-
Ja, du kannst auch einfach nur Funktionsdeklarationen reinstellen. Du musst nicht mit Klassen arbeiten.
Was 'voids' sind, musst du mir aber erklären.
-
Wenn du nur Funktionen auslagern willst, dann schreibst du erst mal nur die Funktionsdeklarationen in den Header. Z.B. so:
#ifndef MEINHEADER_H #define MEINHEADER_H void meinefunktion(int bla, float blub); #endif
dann schreibst du eine Source-Datei, die normalerweise den selben Namen hat, wie die Header-Datei, und die normalerweise die Header-Datei includiert. Dann schreibst du in die Source-Datei die Eigentliche Implementierung der Funktion(en).
#include "meinheader.h" void meinefunktion(int bla, float blub) { // tu dies und das und am besten auch noch jenes }
in die main.cpp inkludierst du dann auch noch die "mein.header.h", machst alles in ein Projekt, rührst einmal um, kompilierst alles und denn läuft dat.
-
Optimizer schrieb:
Ja, du kannst auch einfach nur Funktionsdeklarationen reinstellen. Du musst nicht mit Klassen arbeiten.
Was 'voids' sind, musst du mir aber erklären.Er meint wohl ne funktion, die nix(also void) zurückgibt!
-
ok ich kann da einfach die funktionen reinschreiben, nur mal so zum verständnis, die müsste dann ungefähr so aussehen die datei:
[cpp]#ifndef MEINHEADER_H
#define MEINHEADER_Hvoid meinefunktion(int bla, float blub);
#endif
//---------------------------------void meinefunktion(int bla, float blub)
{
// tu dies und das und am besten auch noch jenes
}oder kommt die funktion anders rein? dass die deklarierung so reinkommt is mir klar. ausserdem wie kompiliere ich den header später geht des automatisch beim kompilieren der datei?
-
Nein, Deklaration und Definition von Funktionen kommen in verschiedene Dateien. Ist das in Ada nicht auch so? Es gibt doch die Trennung in Spezifikation (.ads) und Body (.adb), genauso in C++ ... .h für die Deklaration, .cpp für die Definition. Die .h-Dateien (Header) werden per #include eingebunden. Die cpp-Dateien dagegen werden getrennt übersetzt und zum Schluss zusammengelinkt.
-
um das ganze mal verständlich zu machen, heir ein einfaches Beispiel:
main.cpp:
#include <iostream> #include "addiere.h" using namespace std; int main() { int a, b; cout << "a eingeben: "; cin >> a; cout << "b eingeben: "; cin >> b; cout << "Ergebnis: " << addiere(a, b); return 0; }
addiere.h:
#ifndef ADDIERE_H #define ADDIERE_H int addiere(int a, int b); #endif
addiere.cpp:
#include "addiere.h" int addiere(int a, int b) { return a + b; }
Die Dateien addiere.cpp und main.cpp werden getrennt kompiliert und dass zusammengelinkt. Bei einer IDE brauchst du einfach nur alles in ein projekt zu stecken und dann zu komilieren.
-
Die Dateien addiere.cpp und main.cpp werden getrennt kompiliert und dass zusammengelinkt. Bei einer IDE brauchst du einfach nur alles in ein projekt zu stecken und dann zu komilieren.
Und wie kompiliert man das Programm zum Beispiel mit gcc, ming etc. von der Kommandozeile aus?
Danke,
slartibartfast
-
danke für die ganzen antworten habt mir sehr geholfen, ich hab nur noch eine letzte Frage, ich möchte ein ADT implementieren (Abstrakter Datentyp=steht in ADA zb nur in ads file,also müsste in .h file stehen) geht sowas auch unter c++?
-
Hallo,
in C++ würde man eine Klasse anstelle eines ADTs verwenden.
In C implementiert man einen ADT in der Regel über einen opaque-Pointer.
Z.B. so:#ifndef ADT_EXAMPLE_H_INCLUDED #define ADT_EXAMPLE_H_INCLUDED // opaque-Typ struct MyAdt; typedef struct MyAdt* MyAdtHandle; // auch häufiger gesehen: typedef void* MyAdt // Funktionen zum Anlegen und Zerstören des ADTs void createMyAdt(MyAdtHandle* myAdt); void destroyMyAdt(MyAdtHandle myAdt); // Funktionen des ADTs void funcA(MyAdtHandle myAdt); void funcB(MyAdtHandle myAdt); #endif
Implementiert wird der Typ und seine Funktionen dann in einer c-Datei:
#include "myadt.h" // Implementation ist nur in dieser Datei sichtbar! struct MyAdt { int geheim; }; void createMyAdt(MyAdtHandle* myAdt) { *myAdt = new MyAdt; } void destroyMyAdt(MyAdtHandle myAdt) { delete myAdt; } // Funktionen des ADTs void funcA(MyAdtHandle myAdt) { // ... } void funcB(MyAdtHandle myAdt) { // ... }
Die Benutzung sieht dann etwa so aus:
#include "myadt.h" int main() { MyAdtHandle m; createMyAdt(&m); funcA(m); funcB(m); destroyMyAdt(m); }
Will man im Zusammenhang mit einer C++ Klasse eine ähnlich gute physische Entkopplung von Implementation und Interface, hilft das PIMPL-Idiom. Letztlich dem oberen Code sehr ähnlich:
#ifndef ADT_EXAMPLE_H_INCLUDED #define ADT_EXAMPLE_H_INCLUDED class MyAdt { public: MyAdt(); ~MyAdt(); void funcA(); void funcB(); private: class MyAdtImpl; MyAdtImpl* impl_; // opaque-Pointer }; #endif
Die cpp-Datei:
#include "myadt.h" class MyAdt::MyAdtImpl { int geheim; }; MyAdt::MyAdt() : impl_(new MyAdt::MyAdtImpl) {} MyAdt::~MyAdt() { delete impl_; } void MyAdt::funcA() { // ... } void MyAdt::funcB() { // ... }