definition in header?
-
hallo
soeben, nach vielen compiler fehler *g*, habe ich gelernt wie man header verwendet.
darf dann in header immer nur der deklarationsteil z.B. einer klasse stehen? ich wollte nicht unbedingt immer den definitions teil z.B. in die main.cpp schreiben. oder muss ich dann dafür extra eine .cpp datei für den definitions teil anlegen dort den header implementieren und diese datei dann wiederum in die main.cpp einbinden? aber wenn das so ist woher weiß z.B. iostream wie cout funktioniert das heißt dann dass std::cout schon in der header datei definiert ist oder nicht?irgendwie komm ich hier total durcheinander
danke im voraus
mfg SIDEX
-
SIDEX schrieb:
darf dann in header immer nur der deklarationsteil z.B. einer klasse stehen?
Nicht ganz, aber vorerst: Jep, so isses.
ich wollte nicht unbedingt immer den definitions teil z.B. in die main.cpp schreiben. oder muss ich dann dafür extra eine .cpp datei für den definitions teil anlegen dort den header implementieren und diese datei dann wiederum in die main.cpp einbinden?
Du schreibst eine extra .cpp Datei für die Implementierungen. Dort bindest du auch den Header ein. Dann bindest du diese Datei aber nicht in die main.cpp ein (das würde ja genauso wirken, als stünden die Definitionen im Header), sondern du compilierst beide Quelldateien getrennt und linkst sie zusammen -- falls du eine IDE benutzt, fügst du die Implementierungsdatei dem Projekt hinzu.
aber wenn das so ist woher weiß z.B. iostream wie cout funktioniert das heißt dann dass std::cout schon in der header datei definiert ist oder nicht?
In dem Fall ja, aber das ist ein Sonderfall. Eigentlich schert es C++ nicht, was du in Header schreibst oder sonstwohin, das entscheidende ist hier die One-Definition-Rule (ich würd hier eigentlich gern einen Link auf HumeSikkins' FAQ setzen, aber die Seite gibts anscheinend nicht mehr?), und die besagt, dass jede Definition nur einmal im gesamten Programm vorkommen darf. Davon ausgenommen sind Klassendefinitionen, Inline-Funktionen sowie Templates (und bestimmt noch ein paar andere Sachen die ich bei sowas immer vergesse und die dann Hume nachreicht), wobei diese Ausnahmen jeweils Token für Token identisch sein müssen. Und die gesamte iostream-Bibliothek besteht eben nur aus Templates, d.h. sie ist komplett im Header definiert. Es gibt aber Bibliotheksbestandteile, deren Definitionen ausgelagert sind, insbesondere die C-Header cstdio, cmath, ctime usw. Der Linker sorgt dann dafür, dass sie mit ins Programm eingebunden werden.
Edit: Humes FAQ gibts doch, allerdings nicht mehr unter bens.c-plusplus.info:
http://fara.cs.uni-potsdam.de/~kaufmann/?page=GenCppFaqs&faq=ODR#Answ
-
Im Prinzip darfst du in Headern alles machen, was du auch in normalen CPP Dateien darfst.
Das kommt daher, weil der Präpozessor vor den compilieren den Headerinhalt einfach an die Stelle von dem Include einfügt. Quasi, als würdest du ein Copy&Paste der gesamten Datei machen.
Einen Unterschied gibt es aus Sicht des Compilers also nicht.Das er trozdem meckert, liegt daran, dass Dinge nur einmal definiert werden dürfen. Wird der Header von anderen Cpp dateien schon eingebunden, wiederholen sich die Definitionen. Das lässt der Compiler nicht durchgehen.
Der Compiler muss beim c. einer CPP datei nicht wissen, wie eine woanderstehende Funktion funktioniert. Er will nur wissen, wie sie aufgerufen werden muss. (Die Deklaration der Prototypen).
Wie sie funktioniert erfährt er entweder, wenn er die entsprechende CPP datei später selbst compiliert, oder sie ist schon vorcompiliert und der Linker fügt nun alles zusammen.
Hoffe, etwas klarheit gegeben haben zu können.
-
ja auf jeden fall! eure beiden antworten ergenzen sich ganz prima
vorerst danke!
aber eine sache hab ich immer noch nicht verstanden.
also ich benutze dev c++.jetzt habe ich in die header datei den delarations-teil hinzugefügt und sie dann in der implementierungs datei mit #include "header.hpp" eingebunden.
und dann habe ich versucht diese datei ein mal ohne den header und ein mal mit dem header dem projekt hunzufügen.
und es geht nicht! der compiler sagt dass die klasse in meinem fall names "dog" (*g*) nicht deklariert ist.
im prenzip habe ich das so gemacht wie bashar es gesagt hat. funktioniert aber trotzdem nicht, was mach ich denn falsch?
-
es sieht also so aus?
// dog.hpp #ifndef DOG_HPP #define DOG_HPP class dog { public: dog(); }; #endif
// dog.cpp #include "dog.hpp" dog::dog() { /* blah */ }
// main.cpp #include "dog.hpp" int main() { dog d; ]
-
wurderbar! vielen dank! #include "dog.hpp" in der main.cpp hat mir nur gefehlt jetzt funktioniert alles prima!
wenn wir schon dabei sind:
wozu eigentlich?#ifndef DOG_HPP #define DOG_HPP
noch mal danke
-
#ifndef DOG_HPP #define DOG_HPP #endif // DOG_HPP <- Am Ende der Datei
Verhindern das header mehrfach includiert werden
Hund.hpp: #include "Lebewesen.hpp"
Rotweiler.hpp: #include "Hund.hpp"mensch.hpp: #include "Lebewesen.hpp"
Hundebesitzer.hpp #include "Mensch.hpp" // 1. mal Lebewesen.hpp dabei!
Hundebesitzer.hpp #include "Rotweiler.hpp" // 2.mal Lebewesen.hpp dabeiwenn nun über all die sogenannten INCLUDE-GUARDS dabei sind verhindert das beim 2.mal das Header includiert wird, da es schon includiert ist.
MfG