Konstanten definieren?



  • Hallo,
    kann mir jemand sagen wie man am besten, bzw. wo am besten alle Konstanten (z.B. Pi, Erdbeschleunigung, Elementerladung...) in einem C++ Projekt definieren sollte. Das Projekt besteht dabei aus mehreren c++ Files und mehrere Headerfiles. Sollte man eine eigene Headerfile schreiben wo alle Konstanten deklariert und definiert sind und diese dann in den c++ Files inkludieren? Oder wia macht man das am besten?



  • Ich würde mir in nem eigenen Namespace consts definieren und das ganze in nen kleinen Header packen.



  • Was ist genau ein Namespace und wie macht man so was? Hättest du vielleicht ein Beispiel? Wäre nett...



  • Hi,

    Namespaces werden mit

    namespace Hallo{
         }
    

    deklariert, und mit

    using namespace Hallo;
    

    eingebunden.



  • wenn man genau so wie es c++eus vorgeht, kann man auf namespaces gleich verzichten



  • Also ich bin ja noch nicht so der Profi in C++, aber ich würde das mit einer Struktur machen, also:

    struct konstanten
    {
    double Pi;
    double Gravtitation;
    double Federkonstante;
    ....
    } const x = {3.14, 9.81, 5.4,...};
    

    Diese kannst du dann ansprechen mit

    x.Pi;
    x.Gravitation;
    

    [EDIT] Dumm das ich jetzt erst lese das du die Konstanten in mehreren Dateien brauchst....



  • Was macht das für einen Unterschied? Die Lösung ist so oder so unnötig kompliziert.

    /* konstanten.hpp */
    #ifndef KONSTANTEN_HPP
    #define KONSTANTEN_HPP
    
    namespace konstanten
    {
        const double pi = 3.141...;
        const double grav = 9.81...;
        ...
    }
    
    #endif
    

    Und die dann wo nötig per #include einbinden und die Konstanten mit konstanten::grav etc. ansprechen. Wo ist das Problem?

    Und was namespaces sind, solltest du lieber aus einem Buch als aus drei Sätzen in einem Forum lernen.



  • Kommen die Konstanten komplett in den Header? Muss die Wertzuweisung nicht in die cpp datei?



  • noch zu namespaces:

    der namespace (wie von op void beschrieben) kommt in einen header.

    Auf die Konstanten kansst du immer mit namespace::bezeichner zugreifen, also z.B.

    x = konstanten:pi;
    

    Du kannst außerdem die using-direktive einsetzen. Die macht elemente aus einem namespace direct zugänglich:

    void foo()
    {
      using namespace konstanten; // gültig für diesen Block
      double x = 2*pi, y= 1.0/grav;
    }
    

    Außerdem kann man sich auch einzelne bezeichner rausholen:

    void foo()
    {
      using konstanten::pi; // gültig für diesen Block
      double x = 2*pi, y= 1.0/konstanten::grav;
    }
    

    Die using-Direktive kann auch im file scope (also außerhalb jeglichen Blocks) verwendet werden, und gilt dan ab der Position.

    Das ist allerdings recht umstritten - schreibt man das in den header, kann man sich den namespace nämlich sparen. Wir haben eine In-House-Regel, das using-Direktiven im file scope in .cpp-Files erlaubt, aber in .h - files verboten sind. Macht .E. sinn 😉



  • Wozu das ganze mit einer Struktur oder mit Namespace? Das verkompliziert doch alles...
    Ginge es nicht einfach so? Man erzeugt foldende Headerdatei

    /* konstanten.h */ 
    #ifndef KONSTANTEN_H 
    #define KONSTANTEN_H 
    
        const double pi = 3.141...; 
        const double grav = 9.81...; 
        const double e0 = 1,68...;
        ...  
    
    #endif
    

    und inkludiert die Headerdatei in jede c++ Datei mit

    /* datei.cc */ 
    ...
    #include <konstanten.h>
    ...
    

    So habe ich mir das überlegt zu machen. Scheint das einfachste zu sein.
    Nun aber meine Frage: Ist es so sinnvoll bzw. ist es ratsam das so zu machen?
    Ein Expertentip ist gefragt... Vielen Dank!



  • ginthi schrieb:

    Wozu das ganze mit einer Struktur oder mit Namespace?

    Um Namespace Pollution zu vermeiden. (Ohne Namespace müllst Du Dir sonst den globalen N.S. unnötig zu!)

    edit: Satzbau



  • Was spricht gegen die Definition solcher Konstanten via #define? Braucht man z.B. mal pi/4 rechnet das dann der Compiler und man spart eine (zeitaufwendige!) double-Division...



  • Was spricht gegen die Definition solcher Konstanten via #define

    Namespace und Symbol pollution.

    Stell dir einfach mal vor du machst ein

    #define Pi 3.14159267

    und dann ziehst du eine Bibliothek rein z.B. mit

    void foo
    {
       const double Pi = 3.14159267;   // bang. you're dead.
    }
    

    Das größte Problem von #defines ist, das sie sich an überhaupt keinen scope-Regeln halten.

    Und ein ordentlicher compiler kann Pi/4 auch dann ausrechnen wenn es mit const double definiert ist.



  • Cocaine schrieb:

    Was spricht gegen die Definition solcher Konstanten via #define? Braucht man z.B. mal pi/4 rechnet das dann der Compiler und man spart eine (zeitaufwendige!) double-Division...

    Nein. Die Division sparst du auch bei einer echten Konstante. Schliesslich ist der Compiler ja nicht Dumm.

    #define bringt hier keinen Vorteil, nur Nachteile



  • Oh Gott, blos keine #defines! Die sind verteufelt in C++! Einzige Ausnahme sind die Header-Dateien, da es historisch gewachsen ist. Ansonst sollte man immer const verwenden.

    Ob man das ganze in einen Namespace oder struct reinlegt, hängt davon ab, was man von Design hält. Meiner Meinung nach verwirrt ein struct nur! Irgendwann fragt man sich, was das soll und warum man das gemacht hat. Zusätzlich besteht die Gefahr (und das halte ich für fatal!) das irgendjemand (vielleicht man selbst) diese struct INSTANZIERT, obwohl nur consts drin sind. Völlig sinnlos!

    Const sollte man der eigenen Organisation in einen Namespace packen, WENN sie nicht zu einer speziellen Klasse gehören, sondern von vielen anderen eingesetzt werden können.

    Solche Konstanten wie Erdbeschleunigung usw. könnten doch aber evtl. nur für eine Physik-Klasse interessant sein, oder? Dann würde ich sie nur in entsprechende Klasse legen.

    Achja, und natürlich static nicht vergessen. 😉



  • Oh Gott, blos keine #defines! Die sind verteufelt in C++! Einzige Ausnahme sind die Header-Dateien, da es historisch gewachsen ist. Ansonst sollte man immer const verwenden.

    Ob man das ganze in einen Namespace oder struct reinlegt, hängt davon ab, was man von Design hält. Meiner Meinung nach verwirrt ein struct nur! Irgendwann fragt man sich, was das soll und warum man das gemacht hat. Zusätzlich besteht die Gefahr (und das halte ich für fatal!) das irgendjemand (vielleicht man selbst) diese struct INSTANZIERT, obwohl nur consts drin sind. Völlig sinnlos!

    Const sollte man der eigenen Organisation in einen Namespace packen, WENN sie nicht zu einer speziellen Klasse gehören, sondern von vielen anderen eingesetzt werden können.

    Solche Konstanten wie Erdbeschleunigung usw. könnten doch aber evtl. nur für eine Physik-Klasse interessant sein, oder? Dann würde ich sie nur in entsprechende Klasse legen.

    Achja, und natürlich static nicht vergessen. 😉



  • Naja... #defines sind ja nicht schlecht weil sie verteufelt sind, sondern verteufelt, weil sie schlecht sind. Immer schön auf die Kausalkette achten 😉

    #defines sollte man halt nur da und nur soviel verwenden wie es kein entsprechendes C++ - Konstrukt gibt.

    Da es außerhalb des präprozessors keine standardmäßige Implementation von Include Guards gibt, müssen sie da halt ran.



  • Gut gut, jetzt weiß ich also warum. 😉



  • Cocaine schrieb:

    Gut gut, jetzt weiß ich also warum. 😉

    Lies auch mal Kapitel #1 von Effective C++!


Log in to reply