Speichern



  • Noch dazu eine Verständnis Frage. 😃
    Sprich wenn ich "using namespace std;" brauch ich nicht mehr std:: schreiben?
    Und was bedeuetet Namensraum??
    Und wenn ich das nicht mache vor was muss ich das den schreiben (welche gruppen)



  • DerNoob schrieb:

    Noch dazu eine Verstaendnis Frage. 😃
    Sprich wenn ich "using namespace std;" brauch ich nicht mehr std:: schreiben?

    genau

    DerNoob schrieb:

    Und was bedeuetet Namensraum??

    Ein Prefix den man vergeben kann, damit man z.B. beim Erschaffen einer Klasse String nicht mit der Standardklasse String ins Gehege kommt.

    DerNoob schrieb:

    Und wenn ich das nicht mache vor was muss ich das den schreiben (welche gruppen)

    Wenn du std:: und using weglaesst, dann wird die Klasse nicht gefunden. Klassen die in einem Namensraum erstellt wurden, muessen auch mit diesem angesprochen werden. Wurde z.B. deine Klassen in keinem Namensraum deklariert dann musst du auch keinen angeben.



  • Mal ein Beispiel:

    // Problem: zwei unabhängige Entwickler haben eine Funktion func
    // Lösung: namespaces
    
    namespace foo
    {
    	void func();
    }
    
    namespace bar
    {
    	void func();
    }
    
    ...
    
    // rufe func aus foo auf
    foo::func();
    // rufe func aus bar auf
    bar::func();
    
    ...
    
    using namespace foo;
    // rufe func aus foo auf
    func(); // alternativ foo::func
    // rufe func aus bar auf
    bar::func();
    
    // vice versa mit using namespace bar
    ...
    using namespace foo;
    using namespace bar;
    func(); // Fehler welches func ist gemeint?
    foo::func(); // OK, das aus foo
    

    Und die Sachen der Standardbibliothek sind halt im namespace std.
    Damit man das std:: nicht immer schreiben muss, nutzt man using namespace. Schreib das aber nie in Headerdateien!



  • Hey danke für das Beispiel 🙂

    Ich habe immer das

    using namespace std;
    

    unter den

    #includes
    

    . Also ich schreibe einfach

    using namespace std;
    

    und dann brauche ich mir keine gedanken mit dem

    std::
    

    machen?
    Und hat das irgendwelche Nachteile oder Vorteile?



  • DerNoob schrieb:

    Und hat das irgendwelche Nachteile oder Vorteile?

    Der Hauptgrund, warum man oft using namespace std verwendet ist, dass man sich damit ein wenig Tipparbeit spart.

    Ich finde, Tipparbeit zu sparen ist ein schlechtes Argument. Sonst könnte ich ja auch argumentieren, a, b, c wären doch gute Variablen- oder Funktionsnamen, da ich da Tipparbeit spare. In erster Linie sollte ein Programm lesbar und damit wartbar sein.

    Im Header ist das using namespace std tabu. Daher muss man im Header immer mit vollqualifizierten Namen arbeiten, also immer schön das std:: davor schreiben. Und um es einheitlich zu machen, verwende ich den gleichen Stil im cpp.

    Im Grunde ist using namespace irgendwie ein merkwürdiges Feature. Namensräume sind dazu da, um Namen zu trennen. Und mit using namespace fasse ich sie wieder zusammen. Warum hat man sie dann überhaupt getrennt?

    Also meine Empfehlung: lass es weg und schreibe immer schön std::string, std::cout, std::endl, std::vector usw.



  • Bin anderer Meinung. Bei entsprechender Verwendung der Standardbibliothek ist das ganze "std::" for den Funktionsnamen mehr oder weniger nur "noise" ohne Bedeutung und behindert die Konzentration auf das wesentliche.

    Ich meine, was ist klarer:

    std::vector< std::pair<std::string, std::string> >
    

    oder

    vector< pair<string, string> >
    

    ?
    Natürlich kann man ersteres lesen, aber ist das wirklich schneller und leichter verständlich als letzteres?

    Der Hauptgrund für using namespace ist nicht Tipparbeit, sondern Übersichtlichkeit.

    Nachteil ist natürlich, dass man die Eindeutigkeit von Namen etwas untergräbt (siehe Nathans Beispiel)

    Ich halte mich im Grunde so grob an die Regel, wenn ich innerhalb von 5 Zeilen 5 mal std:: stehen habe, kommt ein using namespace davor - außer natürlich in Headern, dort solltest du es wirklich NIE machen.



  • kleiner Troll schrieb:

    Ich halte mich im Grunde so grob an die Regel, wenn ich innerhalb von 5 Zeilen 5 mal std:: stehen habe, kommt ein using namespace davor - außer natürlich in Headern, dort solltest du es wirklich NIE machen.

    Warum nicht ein funktionslokales using namespace ?



  • Gut, hast mich erwischt - hatte mich prinzipiell auf ein globales using namespace bezogen, hätte das aber spezifizieren müssen. Allerdings glaube ich kaum, das man als Anfänger mit solchen Details etwas anfangen kann (vorallem, da es gerade als Anfänger im Normalfall meist keinen Grund gibt, Funktionen im header zu definieren)

    Funktionslokales using ist natürlich ok.

    (noch zur Erklärung für DerNoob, wenn du using namespace in einem header hast, bekommt das jeder der den header inkludet mit aufgewzungen, ob er will oder nicht. Früher oder später bekommst du dann sehr wahrscheinlich compilerfehler im Stile von Nathans Beispiel)



  • kleiner Troll schrieb:

    Ich meine, was ist klarer:

    std::vector< std::pair<std::string, std::string> >
    

    oder

    vector< pair<string, string> >
    

    ?
    Natürlich kann man ersteres lesen, aber ist das wirklich schneller und leichter verständlich als letzteres?

    Dann doch lieber ein nettes typedef statt using namespace:

    typedef std::pair<std::string, std::string> NamePhonenumber;
    typedef std::vector<NamePhonenumber> PhoneBook;
    


  • Oops, jetzt merke ich hab dich falsch verstanden.
    Ja, mach ich natürlich auch - aber wenn ich in 8/10 Funktionen using namespace std; stehen habe und die anderen beiden triviale Einzeiler sind, kann ichs auch gleich am Anfang schreiben.



  • (Der Beitrag davor ging noch an Nexus)

    Jo, dann hast noch ein std::string drinnen (z.b. als Bedingung), ein std::find_if ein std::irgendwas...

    Mal abgesehen davon dass das typedef wirklich sinnvoll ist, weil pair<string, string> nunmal auch wirklich nicht Aussagekräftig ist (das kommt davon wenn man ein kurzes und einfaches Beispiel machen will), kommst du immer noch verdammt schnell zu einer Menge "std::" die nunmal einfach keine Sau interessieren.

    Das ist ja u.a. auch der Vorteil von std::find_if gegenüber z.B. einem möglichem std_find_if - man kann den namespace eben auch allgemein bekannt machen.

    Aber ich danke als Purist schreibst du auch in Methoden einer Klasse Foo für private Variablen immer Foo::x - immer schön eindeutig sein 😉



  • Oha so viele Antworten 😃
    Ist mit "header" gemeint über

    int main()
    

    ?
    Weil mir wurde erklärt vom Lehrer das dieses

    using namespace std;
    

    dafür da ist, dass man nicht mehr bei den includes das .h hinschreiben muss und man automatisch die neueren Bibilotheken hat.
    Stimmt das?
    Und wenn ihr sagt man sollte damit anfang würde ich das gerne.
    Aber ich verstehe nicht richtig wie ich darauf kommen sollte ob ich das vor einem "Switch, Case, If, ..." schreiben muss. Gibt es da eine bestimmte Regel??
    Oder muss man das auf einer Seite nachschlagen ob ich das davor schreiben muss?



  • Ein Header ist eine Datei, die andere via #include einbinden.
    Und alles, was zu der Standardbibliothek gehört ist im namespace std.
    Sachen, die zur Standardbibliothek gehören, bindest du über Header ein, also <iostream> <vector> <cmath> etc.
    Dazu gehören aber nicht Schlüsselwörter.



  • Sorry, dachte du kennst header schon.
    Header sind in erster linie erstmal eine Konvention, d.h. die Sprache selbst schreibt das soweit ich weiß nicht zwingend vor. D.h. da kann alles drinnen stehen was du auch in deinem Programm stehen hast (sollte es aber nicht unbedingt, aber das führt zu weit).

    Wenn du am Anfang #include schreibst fügst du einen header deinem Programm hinzu. Hauptzweck davon ist, Funktionen die du verwenden willst in der Datei, in der du grade arbeitest bekannt zu machen (am Anfang ist das normalerweise nur eine einzige, die für dich "dein Programm" ist).

    #include macht das einfach nur, indem es den Text aus dem header nimmt und 1 zu 1 in deine Quelldatei kopiert. Mehr passiert da nicht.

    Header werden üblicherweise mit ".h" beendet (.hpp gibt's auch, das ist aber alles auch nur Konvention). Die alten header aus der c-standardbibliothek sehen auch so aus. In C gab es aber noch keine namespaces/Namensräume. Man konnte diese c-header also einfach inkludieren, und sofort war alles bekannt - und man konnte erwähnte Probleme mit der uneindeutigkeit bekommen.

    Die header ohne .h sind die neuen c++ header - wenn sie nur das selbe enthalten wie die C variante, ist der Unterschied eigentlich nur, das hier die Funktionen im Namensraum std liegen, und entweder mit using namespace std; allgemein bekannt gemacht werden müssen, oder aber explicit mit std:: davor benannt werden müssen. Das macht es eben leichter uneindeutigkeiten zu vermeiden.



  • Ich habe schon mal überlegt die Header bei meinen kleinen Projekten einfach komplett wegzulassen.


  • Mod

    DerNoob schrieb:

    Oha so viele Antworten 😃
    Ist mit "header" gemeint über

    int main()
    

    ?

    Header sind die Dinger, die du mittels #include einbindest. Da stehen Signaturen von Funktionen drin, werden Klassen drin definiert, usw.

    Weil mir wurde erklärt vom Lehrer das dieses

    using namespace std;
    

    dafür da ist, dass man nicht mehr bei den includes das .h hinschreiben muss und man automatisch die neueren Bibilotheken hat.
    Stimmt das?

    Nein, das ist absoluter, vollkommener Unsinn. Ich fürchte, dein Lehrer hat selber keine Ahnung.

    Und wenn ihr sagt man sollte damit anfang würde ich das gerne.
    Aber ich verstehe nicht richtig wie ich darauf kommen sollte ob ich das vor einem "Switch, Case, If, ..." schreiben muss. Gibt es da eine bestimmte Regel??

    Ja. Das eine sind elementare Sprachelemente (switch, case, if, ...), das andere bezieht sich auf Funktionen, Klassen und Objekte der Standardbibliothek. Letztere sind alle im Namespace std. Außer, du nutzt alte C-Header (die mit .h) dran), da sind sie global. Achtung: Makros der Standardbibliothek (z.B. assert, XXX_MIN und XXX_MAX) sind nicht in Namespaces. Makros sind kein "richtiger" Bestandteil der Sprache und halten sich nicht an viele Regeln, die sonst gelten.

    Das Problem für dich wird nun wohl sein, dass du nicht sauber zwischen den Schlüsselworten der Sprache und zwischen den Elementen der Standardbibliothek unterscheiden kannst, da du noch nicht vertraut genug bist, mit den verschiedenen Elementen der Sprache. Faustregel: Wenn du für etwas einen Header einbinden musst, dann ist es kein Schlüsselwort der Sprache.

    Oder muss man das auf einer Seite nachschlagen ob ich das davor schreiben muss?

    Allgemeine Referenzen
    en.cppreference.com
    www.cplusplus.com

    Auf diesen Seiten:
    Die Schlüsselworte der Sprache:
    http://en.cppreference.com/w/cpp/keyword
    Du siehst, das sind nicht viele.

    Referenz der Standardbibliothek (umfangreich!):
    http://en.cppreference.com/w/cpp/header
    http://www.cplusplus.com/reference/



  • Hey 😃

    Also so langsam frage ich mich auch was das für ein Lehrer ist.. 😕

    Du hast mir ein Link über die Schlüsselwörter gegeben. Ich dachte Schlüsselwörter wären soetwas wie "cout" oder "cin". Oder sind das Wörter die mit der Bibilothek zusammen hängen? Und die in deinem Link brauchen keine Header Datei?

    Sorry das ich jedzt nochmal Fragen muss aber ich verstehs immer noch nicht richtig...... 😞
    Woran erkenne ich vor welchen Wörtern ich jedzt ein std:: setzten muss?

    ps: Bitte für ganz ganz doofe erklären 😃


  • Mod

    DerNoob schrieb:

    Du hast mir ein Link über die Schlüsselwörter gegeben. Ich dachte Schlüsselwörter wären soetwas wie "cout" oder "cin". Oder sind das Wörter die mit der Bibilothek zusammen hängen?

    Ja, cn und cout sind keine Schlüsselwörter. cin und cout sind zwei globale Variablen vom Typ std::istream bzw. std::ostream. Im Header iostream werden die beiden bekannt gemacht. Referenzen:

    http://www.cplusplus.com/reference/iostream/
    http://www.cplusplus.com/reference/iostream/cin/
    http://www.cplusplus.com/reference/iostream/cout/
    http://en.cppreference.com/w/cpp/io/cin
    http://en.cppreference.com/w/cpp/io/cout

    Und die in deinem Link brauchen keine Header Datei?

    So ist es.

    Woran erkenne ich vor welchen Wörtern ich jedzt ein std:: setzten muss?

    ps: Bitte für ganz ganz doofe erklären 😃

    Daran, dass sie Teil der Standardbibliothek sind. Ja, das ist keine Erklärung für ganz doofe, aber einfacher kann ich es nicht beschreiben. Ich habe ja schon gesagt, dass Dinge, die in Headern definiert werden keine Schlüsselworte sind. Sofern dies ein Header der Standardbibliothek ist (jetzt am Anfang sind vermutlich alle Header, die du benutzt aus der Standardbibliothek, außer du hast sie selber geschrieben), dann sind die dort definierten Bezeichner im Namensraum std (bis auf ganz wenige Ausnahmen).
    Du kannst auch jeweils bei den schon verlinkten Referenzen gucken (die haben eine Suchfunktion), ob und wie die Bezeichner dort auftauchen. Wie du siehst, steht in der Referenz, dass cout eigentlich std::cout heißt und in iostream bekannt gemacht wird. Wenn du hingegen nach "for" suchst, dann findest du gort gar nichts, weil "for" keine Funktion der Standardbibliothek ist, sondern ein grundlegender Teil der Sprache.



  • Schau mal hier nach http://de.cppreference.com/w/. Schluesselwoerter sind Teil der Sprache C++ und Klassen und Funktionen, die mit den C++ Compilern ausgeliefert werden, gehoeren zur Standardbibliothek von C++, deswegen auch der Namensraum std::

    Welche dies nun sind muss du halt lernen.



  • Also müsste ich mich hinsetzen und alles Schlüsselwörter von dem

    #include <iostream.h>
    

    lernen damit ich weiß ob ich davor std:: machen. Oder würde das reichen wenn ich die Schlüsselwörter lerne die keine Header Datei benötigen und bei dem Rest einfach ein std:: davor mache?


Anmelden zum Antworten