Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Aufteilung von Klassen in *.h und *.cpp

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
30.08.2003, 16:11 Uhr
~Einsteiger
Gast


Hallo!

Wieso teilt man in C++ Klassen eigentlich in Header- und Quellcode-Dateien auf? Ist doch technisch auch möglich den ganzen Code in die Headerdatei zu schreiben.
Soll das Programm dadurch übersichtlicher werden? Ich finde eher dass es einfach ist wenn zusammengehörende Klassen auch in eine Datei geschrieben werden.

Außerdem: Wenn ich Klassen aufteile und die Headerdatei in eine andere Klasse einbinde: Woher weiß der Compiler dann wo der eigentliche Code für die Klasse steht?

mfg
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
30.08.2003, 16:31 Uhr
Pablo
Supertux
(Operator)


ich weiß auch wirklich nicht, wieso man das so macht. Aber wenn du dir die Header Dateien genauer anguckst, findest du meistens nur die Deklaration von den Variablen, Klassen, Konstanten usw. Die Header Datei ist sozusagen da, um dem Compiler mitzuteilen: es gibt diese Variable, und diese Klasse usw.

Ich finde schon übersichtlicher, wenn ich in der CPP Datei nur Code habe. Eine Header Datei wird meistens von mehr als eine CPP Datei eingebunden, weil sie nur "wissen wollen", was zur Verfügung steht.

Cer Compiler kompiliert nur, er weiß nicht, wo die Sachen sind. Der sich darum kümmert, den Code von eine Funktion bzw. Klasse zu finden ist der Linker.

Bsp: Das ist ein kleines einfaches Beispiel in Linux mit gcc

C++:
// myhead.h
#ifndef MYHEAD_H
#define MYHEAD_H
#include <stdio.h>
extern char* string; // ohne extern gibt es Ärger, darum kümmerst sich der Linker
void write();
#endif
/////////////////////////////////////////////
// main.c
#include "myhead.h"
int main()
{
    string = ", Welt";
    printf("Hallo%s\n",string);
    write(); // wenn der Compiler das kompiliert, weißt nur, dass es diese Funktion gibt
                // der Linker weißt wo.
    printf("ciao!\n");
}
//////////////////////////////////////////////
//write.c
#include "myhead.h"
char* string;
void write()
{
    printf("Hallo%s\n",string);
}



Jetzt werden wir das kompilieren:

Code:
gcc -c main.c
gcc -c write.c


main.c weißt von myheader, dass die Fuktion write und die Variable string zur Verfügung stehen. Er kompiliert nur den Code, ist ihm aber egal, wo die sich befinden.
write.c implementiert die Funktion und die Variable.

Der Rest ist die Arbeit vom Linker:

Code:
gcc -o write main.o


Das supckt folgeden Fehler:
main.o: In function `main':
main.o(.text+0x8): undefined reference to `string'
main.o(.text+0x14): undefined reference to `string'
collect2: ld returned 1 exit status

Aber

Code:
gcc -o write main.o write.o


erzeugt eine gültige Binäerdatei "write". Der Linker sucht nach diesen beiden Sachen und findet sie in der Datei write.o, deshalb funktioniert es.
Die Ausgabe:

Code:
Hallo, Welt
Hallo, Welt
ciao!



ich hoffe, dass ich dir weitergeholfen hab und nicht die was erzählt hab, was du schon weißt.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!

Dieser Post wurde am 30.08.2003 um 16:32 Uhr von Pablo Yanez Trujillo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
30.08.2003, 18:09 Uhr
~Einsteiger
Gast


Ja, danke. Hat mir weitergeholfen.
Ich werde die Aufteilung hat machen, wenn es jeder so macht - auch wenn ich nicht genau weiß warum eigentlich...

mfg
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
30.08.2003, 18:12 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)


wenn du ein projekt mit mehrern Leuten machst, dann definierst du quasi die Schnittstellen in den Headern.

Wie das ganze dann implementiert ist interessiert den jenigen der die funktion benutzt eigentlich nicht.
Der will nur wissen wie sie heisst und was sie macht.

Banal gesagt deswegen die Aufteilung
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
30.08.2003, 19:31 Uhr
virtual
Sexiest Bit alive
(Operator)


Kurze Anmerkung:
In C und C++ Unterscheidet man zwischen Definition und Deklaration:
Bei Funktionen zB so:

C++:
void f(int x); /* Deklaration */

void f(int x) /* Definition */
{
    printf("%d\n", x);
}


oder

C++:
void f(int x) /* Definition und deklaration (weil expl. Deklaration fehlt)*/
{
    printf("%d\n", x);
}


Bei variablen so:

C++:
extern int a; /* Deklaration */
int a; /*Definition */


oder

C++:
int a; /* Definition und deklaration (weil expl. Deklaration fehlt)*/


Außerdem gibt es in C die sog. "One-Definition-Rule": Zu allem darf es nur eine Definition geben. Wenn ich nun etwas in den header stopfe, dann würde es - weil ich in verschiednen Übersetzungseinheiten (== .c File) den Header includieren kann, mehrere Definition der gleichen Funktion/Variable geben. Ausnahmen bilden Templates (weil sie in einer speziellen Art definiert werden) und inline Funktion.
Naturgemäß kann man in Header als nur Deklarationen unterbringen; man hätte auch theoretisch auf Header verzichten können - es gab im Zusammenhang mit der Standardisierung von C++ entsprechende überlegungen), aber man hat es aus verschiedenen Erwägungen dabei belassen. Ein ganz netter Nebeneffekt der Sache mit den Headern ist, daß die Turnaround Zeit niedrig bleibt: der Compiler braucht nur einen vergleichweisen kleinen Header ohne komplizierten Code zu parsen und nicht immer den ganzen Kram. Ich denke, das war eine der Hauptargumente damals, als Rechenzeit knapp und teuer war, sich auf das Headerkonzept einzulassen.
Und natürlich das, was Windalf erklärt hat: eigentlich geht es niemanden an, wie eine Funktionen innen drin aussieht. - Die header unterstützen also Kapselung und Geheimnisprinzip.

Nichtsdestortrotz kann man in C++ natürlich ganz auf .cpp Dateien verzichten und alles in den header reinschreiben - muß dann eben alles inline sein (sieht dann einem Javafile recht ähnlich). Nur so empfehlen kann ich Dir das nicht, aus og Überlegungen
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
30.08.2003, 19:34 Uhr
Pablo
Supertux
(Operator)



Zitat:
virtual postete
Kurze Anmerkung:
In C und C++ Unterscheidet man zwischen Definition und Deklaration:



Es kann sein, dass ich falsch gesagt habe. Ich hab die Gewohnheit diese Namen zu verwechseln.

(Übrings, sagt man: ich verwechsle? Das hört sich jetzt nicht so gut für mich an)

Was ist genau eine inline Funktion? Ich hab mehrmals das gesehen, nie benutzt und ich verstehe nicht ganz, wozu das gut sein soll.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!

Dieser Post wurde am 30.08.2003 um 19:36 Uhr von Pablo Yanez Trujillo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
31.08.2003, 00:25 Uhr
Marty



@Pablo

1. Ich denke man hat zwei Möglichkeiten: "ich verwechsle" oder "ich verwechsele"

2. Eine inline-Funktion wird vom Compiler anders behandelt: intern wird der Funktionsinhalt an jede Stelle kopiert wo die Funktion gerufen wird. Das hat sowohl Vor- wie auch Nachteile, die bei der Verwendung beachtet werden müssen:

Vorteile:
- schnellerer Code, da der Aufruf des Funktionsoverheads entfällt

Nachteile:
- Größere Programmdateien, da ja jedesmal die gesamte Funktion eingefügt wird
- naturgemäß keine Rekursion möglich
--
MfG,
Marty

Ein Mensch sieht ein, und das ist wichtig, nichts ist ganz falsch und nichts ganz richtig.
(Eugen Roth)

Dieser Post wurde am 31.08.2003 um 00:38 Uhr von Marty editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
31.08.2003, 00:51 Uhr
Pablo
Supertux
(Operator)


Danke für die Erklärung.
--
A! Elbereth Gilthoniel!
silivren penna míriel
o menel aglar elenath,
Gilthoniel, A! Elbereth!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
31.08.2003, 07:06 Uhr
virtual
Sexiest Bit alive
(Operator)


@Marty
Da inline nur eine Empfahleng an den Compiler ist, können die natürlich auch rekursionen enthalten. Du hast ohnehin keine Kontrolle darüber, ob sie wirklich zu inlines expandiert werden.

Zu den Nachteilen grhört auch:
-höhere Kopplung der Überstzungenheiten
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
31.08.2003, 12:23 Uhr
Marty



@virtual

Danke für die Korrektur!
--
MfG,
Marty

Ein Mensch sieht ein, und das ist wichtig, nichts ist ganz falsch und nichts ganz richtig.
(Eugen Roth)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: