• Diese Seite verwendet Cookies. Indem du diese Website weiterhin nutzt, erklärst du dich mit der Verwendung von Cookies einverstanden. Erfahre mehr

CPP Header und Sourcen Includes....

Sadakazu

Well-Known Member
Themenstarter #1
Moin moin....
Mal eben ne doofe Frage...

Ich meine irgendwo - ich glaube sogar hier - mal ein Kommentar bekommen zu haben, das man seine Headers frei von #includes halten sollte und alles nur die die cpp packen soll.

so jetzt hab ich aber das Problem wenn ich zb den string nicht inkludiere, das a) die IDE meckert und b) der Compiler den dienst quittiert...

Also müssen doch die includes wie string vector map und co mit in die Header rein oder nicht?
Aber jetzt frage ich mich...
Warum muss ich sie dann nochmal in der cpp datei mit includieren, wenn sie über die header schon includiert sind?

Kann ja durchaus sein, das ich das falsch verstanden habe und man meinte, alles in die Headers aber nix in die cpp außer die Klassenheader....
Wenn ich das aber mache meckert auch wieder a) die IDE und b) der Compiler....

Gibt mir jetzt den aufschluss das man immer und überall includen muss?

Ich hab mir auf Udemy son einsteiger Kurs gekauft... war im "angebot" 10 euro... kann man nix verkehrt machen...

Aber der Dozent hat auch in beiden files alle includes drin.....

So... daher jetzt die frage...
Was bitteschön ist jetzt richtig?
a) überall immer alles includen?
b) nur in Header includen?
c) nur in CPP includen?

Und wenn b oder c....
Was mach ich bitte falsch? :D
 

KobRheTilla

used register
#2
Vielleicht zeigst du mal ein kleines Beispiel, was dir um die Ohren fliegt. Dann kann man eventuell besser Tipps geben.
Ich kenne es so, dass in die Header nur Definitionen von Funktionen und Datentypen kommen, kein Programmcode.
Den Header bindet man dann in den Quelltexten ein, die diese Funktionen/Datentypen nutzen möchten.

Rob
 

Rakor

Administrator
Mitarbeiter
#3
Und welechen Hintergrund diese Forderung haben soll. Ich kenne es so, dass die Includes in den Header kommen und nur so ist es meiner Meinung nach sinnvoll und übersichtlich.
 
#4
Ich packe die Includes die zum Interface gehören (also die Argumente der Funktionen/Methoden definieren) in den Header und diejenigen die nur im der Implementation verwendet werden in die cpp Datei. Die Idee ist die Interfaces so minimal als möglich zu gestalten was evtl.Kompilierzeit und weitere Abhängigkeiten im Falle von Biblotheken reduziert. Alles in den Header zu packen ist während der Entwicklung oft bequemer. Ist aber alles nicht so besonders relevant und hängt ein wenig davon ab was du machst, - kein Anlass für Grundsatzdiskussionen ;)

Bei C++ müssen natürlich Templates und Inlines in die Header. Insofern die die Unterscheidung von cpp/hpp ein wenig künstlich.
 

Sadakazu

Well-Known Member
Themenstarter #5
eeeehhhhhhh ok....
Dann lag der Fehler woanders....

Hab jetzt grad mal was ganz Triviales gemacht....

Header:
Code:
#ifndef SIMPLETEST_H_
#define SIMPLETEST_H_

#include <iostream>
#include <string>
class SimpleTest {
public:
   SimpleTest();
   virtual ~SimpleTest();

   std::string printSometh(std::string &out);
};

#endif /* SIMPLETEST_H_ */
CPP
Code:
#include "SimpleTest.h"

SimpleTest::SimpleTest() {
   // TODO Auto-generated constructor stub

}

SimpleTest::~SimpleTest() {
   // TODO Auto-generated destructor stub
}

std::string SimpleTest::printSometh(std::string &out) {
   return out;
}
Main
Code:
#include <iostream>
#include <string>

#include "SimpleTest.h"

int main() {

   SimpleTest test;

   std::string blub = "Hallo WElt";

   std::cout << test.printSometh(blub) << std::endl;
}
Funktioniert....
Also.... ALLES an includes in den Header mit rein....

NIX im CPP ....

Ich meine aber echt das mir jemand mal gesagt hatte es muss dort rein, wo man es auch benutzt.... oO hm...

[EDIT]
Jetzt nicht über den sinn bzw vielmehr unsinn diskutieren, warum ich einen string übergebe um einen string zurück zu bekommen....
ich weiß selber das das total dumm ist... sollte auch nur zur Veranschaulichung dienen... genauso hätte der rückgabewert jetzt ne map sein können... oder etwas in eine map reinpacken können oder was auch immer....
 
C

CrimsonKing

Guest
#6
Mein Verständnis sagt mir: Der Header definiert einen std::string, also muss er wissen, was das überhaupt ist.
 

goblin

Dämonenbeschwörer
#7
Die STL besteht, wie der name Standard Template Library schon sagt, hauptsächlich aus Template-Code. Und im Allgemeinen verlangt ein C++-Compiler alle Definitionen der Templates zur Compilezeit, weswegen Template-reicher Code oft header only implementiert wird. Das ist nicht zwingend vorgeschrieben, es gibt auch die Möglichkeit Template-Spezialisierungen vorzudeklarieren und den tatsächlich spezialisierten Code dann erst zum Linken hinzuzufügen. Dies ist aber etwas umständlich und fehleranfällig, weshalb es eigentlich nur dann gemacht wird, wenn die Dauer des Compiliervorgangs durch die vielen immer wieder geparsten Templates zu sehr ansteigt.

An sich hast du aber recht, im Prinzip ist das Ziel möglichst wenig Code in Headern einzubinden. Aber natürlich muss der Compiler alle verwendeten Datenstrukturen kennen. Da deine Beispielklasse std::string verwendet musst du auch string includen. Es gibt zwar die Möglichkeit nur mit Vorwärtsdeklarationen zu arbeiten, wenn nur Zeiger oder Referenzen eines Datentyps verwendet werden, aber bei template-basiertem Code wird das oft sehr aufwendig.
Deine Implementierungsdatei (simpletest.cpp?) Enthält nicht wirlkich viel Code, daher werden keine besonderen Header-Dateien gebraucht.
Den iostream-Header musst du erst in main.cpp einbinden, da nur dort std::cout und std::endl verwendet werden.

Hilfreich ist die Faustregel:
Der Compiler muss wissen, wie viel Speicher jeder Datentyp braucht, entsprechend braucht er die Definition dann, wenn er Speicher reservieren muss. Wenn nur Zeiger oder Referenzen weitergereicht werden, dann ist dieses Wissen nicht notwendig und eine Vorwärtsdeklaration ist ausreichend.
 

Sadakazu

Well-Known Member
Themenstarter #8
Gut das Beispiel mit der Simple test war auch extrem trivial...
und ja... <iostream> ist überflüssig.. hatte zuerst in der printSometh() nen cout drin.... bis mir auffiel das das ja blödsinn ist da ich ja den str eh zurück gebe....

War mal eben in 20 sekunden hingeklatscht....


Mein Verständnis sagt mir: Der Header definiert einen std::string, also muss er wissen, was das überhaupt ist.
da ich aber noch nicht soooo lange programmiere (halbes jahr mit pause) habe ich halt auch noch nicht die erfahrung wie jemand der das seit jahren täglich praktiziert...
Und weil ich ein bisschen verwirrt war wollt ich das halt nochmal genau klargestellt wissen....

Kurz um.... includes gehören in den Header... in der cpp nur implementation und klassenheader include....

bzw.. wie sieht das aus wenn ich in der cpp in einer methode als "temporären datentyp" zb ne map brauche
es gibt weder rückgabewerte vom typ map noch wird eine map als parameter entgegengenommen...
brauche die map aber um zb int und string werte (die über die parameterliste rein kommen) in einer map abspeichern will.... oder eben als vektor oder pair um es mit irgendwas anderes zu verlgiechen.. oder was auch immer... (mir fällt grad kein sinnvolles anwendungsbeispiel ein)

aber WO wird da jetzt meine map inkludiert... im Header? oder in der source File?

Ansonsten hat sich meine frage erübrigt.. ^^
 
C

CrimsonKing

Guest
#9
Technisch gesehen ist das vollkommen egal, was du wo hinschiebst, so lange es kompiliert und läuft. :belehren:
 

Sadakazu

Well-Known Member
Themenstarter #10
ging halt nur um die frage.... wo es "schöner zu lesen" wäre...
wenns im header stehen würde und jemand nur den header liest und über ein include stolpert das nirgendwo - scheinbar - benutzt wird... könnte dazu animieren den include zu entfernen....
Könnte ich mir jedenfalls vorstellen.....
 

goblin

Dämonenbeschwörer
#12
ging halt nur um die frage.... wo es "schöner zu lesen" wäre...
wenns im header stehen würde und jemand nur den header liest und über ein include stolpert das nirgendwo - scheinbar - benutzt wird... könnte dazu animieren den include zu entfernen....
Könnte ich mir jedenfalls vorstellen.....
Einmal das, zum Anderen verlängert es die Compilierzeit, denn in größeren Projekten wird ein Header in mehr als nur einer Datei includiert. Wenn dort includes drin sind, die zum Verwenden der im Header deklarierten Konstrukte nicht notwendig sind, dann sind sie in den anderen Quellcodedateien eventuell unnötig.

Ansonsten stimme ich Crimson King zu, technisch gesehen ist es egal solange es kompiliert.
 
#14
Klar, aber duzende von #ifdef in hunderten von Headern akkumuliert sich schon. Außerdem macht es die Header unnötig schwer leserlich. Das alles ist aber keine religiöse Frage! ;)
 

Sadakazu

Well-Known Member
Themenstarter #15
Wie siehts eigentlich aus....
#ifdef oder #pragma once? welches sollte man ehr benutzen und warum?
Streiten sich ja scheinbar auch die Geister drum.... der Dozent auf udemy meinte jedenfalls das er lieber das #pragma once nutzt.....

Eclipse erstellt mir aber immer alles mit dem #ifdef usw...